Koristim Indy 9 i D7, pravio sam neku aplikaciju za firmu, sistemski podaci o klijentima (klijent - server - InfoApp koji preuzima podatke i prikazuje korisniku).
Testirao sam je, i na mom racunaru sve lepo radi. Medjutim kad sam exe prosledio kolegi (koji se nalazi u lokalnoj mrezi), njemu je nakon nekog vremena stao program.
Pokusao sam od kuce da se nakacim na VPN mrezu i pustim InfoApp da radi i stvarno posle nekog vremena blokira kompletan program. Ubacio sam logove na kriticnim pozicijama u programu i ustanovio da ReadStream se ponekad jednostavnu zbuni i zaustavi sve.
Sa servera (na zahtev InfoApp) saljem velicinu stream-a i zatim citam po broju bajtova.
Evo koda:
Server:
Code:
procedure TfrmMain.idTcpServerCmdSendListToAppCommand(ASender: TIdCommand);
begin
ListToStream(MainMemStream, ClientsList); //pretvara TThreadList u Stream
MainMemStream.Position := 0;
ASender.Thread.Connection.WriteInteger(MainMemStream.Size); //nakon sto posalje velicinu stream-a stane
ASender.Thread.Connection.WriteStream (MainMemStream);
ASender.Thread.Connection.WriteBuffer(SettingsClient, SizeOf(SettingsClient));
end;
procedure TfrmMain.idTcpServerCmdSendListToAppCommand(ASender: TIdCommand);
begin
ListToStream(MainMemStream, ClientsList); //pretvara TThreadList u Stream
MainMemStream.Position := 0;
ASender.Thread.Connection.WriteInteger(MainMemStream.Size); //nakon sto posalje velicinu stream-a stane
ASender.Thread.Connection.WriteStream (MainMemStream);
ASender.Thread.Connection.WriteBuffer(SettingsClient, SizeOf(SettingsClient));
end;
InfoApp:
Code:
function TfrmMain.GetListFromServer(var MemStr: TMemoryStream): Boolean;
var
I: Integer;
begin
Result := False;
UpdateLog('GetListFromSErver');
with IdTCPClient do
begin
try
acRefresh.Enabled := False;
UpdateLog('Connecting...');
if not Connected then Connect(2000);
try
UpdateLog('connected');
WriteLn('SendListToApp');
UpdateLog('SendListToApp');
I := ReadInteger; //uredno iscita velicinu stream-a i stane, ovo sam resio sa ReadTimeOut property-jem, samo aplikacija bi trebalo da odrzi vezu, bar u lokalnoj mrezi
UpdateLog('Read integer ' + IntToStr(I));
MemStr.Clear;
ReadStream (MemStr, I);
ReadBuffer(SettingsClient, SizeOf(TSettingsClient));
UpdateLog('Read Settings ' + 'Size ' + IntToStr(Sizeof(TSettingsClient)));
ConnectionResultDis(True);
Result := True;
UpdateLog('Quit');
SendCmd('Quit');
UpdateLog(IdTCPClient.LastCmdResult.TextCode);
finally
DisconnectSocket;
UpdateLog('Diskonected!');
acRefresh.Enabled := True;
end;
except
on E:EIdException do
begin
UpdateLog('Exception ' + E.Message);
ConnectionResultDis(False);
acRefresh.Enabled := True;
Result := False;
end;
on E: EIdReadTimeout do
begin
UpdateLog('ReadTimeout' + e.Message );
ConnectionResultDis(False);
acRefresh.Enabled := True;
Result := False;
end;
end;
end;
end;
function TfrmMain.GetListFromServer(var MemStr: TMemoryStream): Boolean;
var
I: Integer;
begin
Result := False;
UpdateLog('GetListFromSErver');
with IdTCPClient do
begin
try
acRefresh.Enabled := False;
UpdateLog('Connecting...');
if not Connected then Connect(2000);
try
UpdateLog('connected');
WriteLn('SendListToApp');
UpdateLog('SendListToApp');
I := ReadInteger; //uredno iscita velicinu stream-a i stane, ovo sam resio sa ReadTimeOut property-jem, samo aplikacija bi trebalo da odrzi vezu, bar u lokalnoj mrezi
UpdateLog('Read integer ' + IntToStr(I));
MemStr.Clear;
ReadStream (MemStr, I);
ReadBuffer(SettingsClient, SizeOf(TSettingsClient));
UpdateLog('Read Settings ' + 'Size ' + IntToStr(Sizeof(TSettingsClient)));
ConnectionResultDis(True);
Result := True;
UpdateLog('Quit');
SendCmd('Quit');
UpdateLog(IdTCPClient.LastCmdResult.TextCode);
finally
DisconnectSocket;
UpdateLog('Diskonected!');
acRefresh.Enabled := True;
end;
except
on E:EIdException do
begin
UpdateLog('Exception ' + E.Message);
ConnectionResultDis(False);
acRefresh.Enabled := True;
Result := False;
end;
on E: EIdReadTimeout do
begin
UpdateLog('ReadTimeout' + e.Message );
ConnectionResultDis(False);
acRefresh.Enabled := True;
Result := False;
end;
end;
end;
end;