Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Indy ReadStream problem

[es] :: Pascal / Delphi / Kylix :: Indy ReadStream problem

[ Pregleda: 1899 | Odgovora: 3 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

krle_zr

Član broj: 96307
Poruke: 258
*.dynamic.isp.telekom.rs.



+7 Profil

icon Indy ReadStream problem13.03.2011. u 08:29 - pre 159 meseci
Imam jedan jako cudan problem sa ReadStream funkcijom.
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;



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;

 
Odgovor na temu

savkic
Igor Savkić

Moderator
Član broj: 92186
Poruke: 2739



+92 Profil

icon Re: Indy ReadStream problem14.03.2011. u 11:12 - pre 159 meseci
> Koristim Indy 9 i D7, pravio sam neku aplikaciju za firmu,

Trebaš probati i Indy 10.

> 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.
> 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));

Ako je početak buffera oštećen onda možeš dobiti neispravan broj, prilično veliki tako da se čitanje ne može nikada završiti.

> ReadStream (MemStr, I);

Tipujem da je problem što tražiš veći broj bajtova nego što je dostupno, proveri da li imaš podešen ReadTimeout.
ReadStream se svodi posle na ReadBuffer i ReadFromStack, negde u njima dolazi do zamrzavanja, najbolje da pustiš program kroz debugger i uđeš direktno u Indy kod da vidiš gde je tačno nastao problem, to će ti ujedno reći i zašto.
 
Odgovor na temu

krle_zr

Član broj: 96307
Poruke: 258
*.dynamic.isp.telekom.rs.



+7 Profil

icon Re: Indy ReadStream problem14.03.2011. u 15:26 - pre 159 meseci
Citat:
savkic

Ako je početak buffera oštećen onda možeš dobiti neispravan broj, prilično veliki tako da se čitanje ne može nikada završiti.



Ubacio sam log proceduru i interesantno, dobijam isti broj bajtova pri iscitavanju;

Code:


13.03.2011 21:30:40 : StreamToList
13.03.2011 21:30:40 : RefreshLists...
13.03.2011 21:32:40 : GetListFromSErver
13.03.2011 21:32:40 : Connecting...
13.03.2011 21:32:40 : connected
13.03.2011 21:32:40 : SendListToApp
13.03.2011 21:32:40 : Read integer 158470
13.03.2011 21:32:42 : Read Settings Size 547
13.03.2011 21:32:42 : ConnectResultDis True
13.03.2011 21:32:42 : Quit
13.03.2011 21:32:42 : 200
13.03.2011 21:32:42 : Diskonected!

13.03.2011 21:32:42 : StreamToList
13.03.2011 21:32:42 : RefreshLists...
13.03.2011 21:32:53 : TrayIconClick...
13.03.2011 21:32:53 : TrayIconClick...end
13.03.2011 21:32:54 : Osvezavam...
13.03.2011 21:32:54 : GetListFromSErver
13.03.2011 21:32:54 : Connecting...
13.03.2011 21:32:54 : connected
13.03.2011 21:32:54 : SendListToApp
13.03.2011 21:32:54 : Read integer 158470 // u toku prenosa stane i izbaci exception 
13.03.2011 21:32:58 : Diskonected!
13.03.2011 21:32:58 : Exception Read Timeout



Citat:
savkic:

Tipujem da je problem što tražiš veći broj bajtova nego što je dostupno, proveri da li imaš podešen ReadTimeout.
ReadStream se svodi posle na ReadBuffer i ReadFromStack, negde u njima dolazi do zamrzavanja, najbolje da pustiš program kroz debugger i uđeš direktno u Indy kod da vidiš gde je tačno nastao problem, to će ti ujedno reći i zašto.


ReadTimeout mi je podesen na 2000 ms i nakon toga se otkaci. Pustio sam program kroz debugger (bez ReadTimeout), medjutim ne zaustavlja se nigde.
Moracu da pogledam da slucajno dva ili vise thredova ne prave problem, posto sve citam iz jednog glavnog stream-a.

savkic, hvala u svakom slucaju.
 
Odgovor na temu

savkic
Igor Savkić

Moderator
Član broj: 92186
Poruke: 2739



+92 Profil

icon Re: Indy ReadStream problem14.03.2011. u 20:05 - pre 159 meseci
> ReadTimeout mi je podesen na 2000 ms i nakon toga se otkaci. Pustio sam program kroz debugger (bez ReadTimeout), medjutim ne zaustavlja se nigde.

Kada se zamrzne onda pusti debugger u nekim od tih metoda.

> Moracu da pogledam da slucajno dva ili vise thredova ne prave problem, posto sve citam iz jednog glavnog stream-a.

Znači koristiš jednu konekciju iz više threadova? Ne smeš to tako, Indy po defaultu za svaku konekciju pravi novi thread, nemoj to menjati.
 
Odgovor na temu

[es] :: Pascal / Delphi / Kylix :: Indy ReadStream problem

[ Pregleda: 1899 | Odgovora: 3 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.