![]() |
Indy10: TIdIOHandler.ReadLn hängt Programm auf
Hallo,
in einem eigenständigen Thread verwende ich eine Ableitung von TIdTCPClient. Der Thread selbst durchläuft in seiner Execute Methode eine Schleife
Delphi-Quellcode:
An der markierten Stelle hängt sich das Programm einfach auf, wenn ich die Zeile auskommentier funktioniert es perfekt.
procedure TClientReader.Execute;
var LReadString : AnsiString; begin while not Terminated do begin sleep(10); try if Assigned(FClient)and Assigned(FClient.IOHandler)and FClient.Connected then try FClient.IOHandler.ReadTimeout:=1000;//Test LReadString:= FClient.IOHandler.ReadLn;//Hier hängt sich das Programm einfach auf if(Length(Trim(LReadString))>0)then begin if Assigned(FClient.ReaderEvent)then begin FClient.ReaderEvent(LReadString); end; end; except on e : EIdClosedSocket do SNLogger.Log('TClientReader.Execute:EIdClosedSocket:'+e.ClassType.ClassName+':'+e.message); on e : EIdReadTimeout do SNLogger.Log('TClientReader.Execute:EIdReadTimeout:'+e.ClassType.ClassName+':'+e.message); on e : EIdException do SNLogger.Log('TClientReader.Execute:EIdException:'+e.ClassType.ClassName+':'+e.message); on e : exception do SNLogger.Log('TClientReader.Execute:Exception:'+e.ClassType.ClassName+':'+e.message); end; except on e : exception do begin SNLogger.Log('TClientReader.Execute:'+e.ClassType.ClassName+':'+e.Message); exit; end; end; end; Es kommt keine Exception :( Das Programm hängt sich auch nicht bei jedem Durchlauf auf, sondern erst nach einiger Zeit. Ich habe wie ihr seht ein Timeout probiert, jedoch ohne Erfolg. Jetzt ist mir eingefallen, dass TIdAntiFreeze für solche Fälle nützlich sein kann und ich hab eins auf das Formular der Unit gezogen, in der dieser Thread verwendet wird, allerdings auch ohne Erfolg. Ich bin mir jetzt nicht sicher wie das TIdAntiFreeze arbeitet, ob ich das in diesem Fall woanders einfügen muss. Habt Ihr eine Idee warum sich das Programm da aufhängt? Es hängt sich auch nur unter Windows XP auf, unter Windows 7 hatte ich bisher keine Probleme. |
AW: Indy10: TIdIOHandler.ReadLn hängt Programm auf
Ich bin mir nicht 100% sicher aber ich denke dass ReadLn auf einen terminator warted, der default ist #13#10 [end of line] und ich hatte ein ziemlich aenliches problem gehabt mit Indy.
Ich denke das dein problem in der (Sender) writeln liegt nicht in der readln ... |
AW: Indy10: TIdIOHandler.ReadLn hängt Programm auf
Danke für den Tipp, hat aber leider nicht geholfen.
Ich arbeite beim Sender mit writeln, welches ja schon dieses EOL zeichen anhängt, und habe jetzt durch deinen Hinweis zusätzlich noch sLineBreak, also #13#10 drangehängt, das Programm hängt sich aber immernoch auf :( |
AW: Indy10: TIdIOHandler.ReadLn hängt Programm auf
Hallo Martin,
schau Dir mal bitte das Beispiel von Remy an: ![]() Daraus zitiert:
Delphi-Quellcode:
Gruß,
procedure TFormMain.IdTCPServerExecute(AContext: TIdContext);
var RxBuf: TIdBytes; begin RxBuf := nil; with AContext.Connection.IOHandler do begin CheckForDataOnSource(10); if not InputBufferIsEmpty then begin InputBuffer.ExtractToBytes(RxBuf); // process RxBuf as needed... end; end; end; Alternativ: procedure TFormMain.IdTCPServerExecute(AContext: TIdContext); var RxBufStr: String; // not UTF8String begin with AContext.Connection.IOHandler do begin CheckForDataOnSource(10); if not InputBufferIsEmpty then begin RxBufStr := InputBuffer.Extract(-1, enUtf8); // Alternatively to above, you can set the // InputBuffer.Encoding property to enUtf8 // beforehand, and then call TIdBuffer.Extract() // without any parameters. // // Or, set the IOHandler.DefStringEncoding // property to enUtf8 beforehand, and then // call TIdIOHandler.InputBufferAsString() // process RxBufStr as needed... end; end; end; Assertor |
AW: Indy10: TIdIOHandler.ReadLn hängt Programm auf
Hast du es mit einem custom terminator vesucht, ich gebrauche z.b. ^^ als terminator.
|
AW: Indy10: TIdIOHandler.ReadLn hängt Programm auf
Wie wende ich diesen custom terminator an?
Ich denke mal ich hänge den beim writeln einfach an die Zeile an, aber was muss ich dann beim readln machen damit nur bis zu diesem Terminator gelesen wird?? Edit: Huch, den Post von Assertor hab ich garnich gesehn, schau ich mir gleich an Edit2: Habs jetzt mal umgebaut, aber jetzt kommt im Client scheinbar garnichtsmehr an. Muss ich auch den Server irgendwie umbauen?
Delphi-Quellcode:
procedure TClientReader.Execute;
var LReadString : AnsiString; LBuf : TIdBytes; begin while not Terminated do begin sleep(10); try if Assigned(FClient)and Assigned(FClient.IOHandler)and FClient.Connected then begin with FClient.IOHandler do try CheckForDataOnSource(10); if not InputBufferIsEmpty then // InputBufferIsEmpty ist immer true begin LBuf:=nil; InputBuffer.ExtractToBytes(LBuf); LReadString:= BytesToString(LBuf); if(Length(Trim(LReadString))>0)then begin if Assigned(FClient.ReaderEvent)then begin FClient.ReaderEvent(LReadString); end; end; end; except on e : EIdClosedSocket do SNLogger.Log('TClientReader.Execute:EIdClosedSocket:'+e.ClassType.ClassName+':'+e.message); on e : EIdReadTimeout do SNLogger.Log('TClientReader.Execute:EIdReadTimeout:'+e.ClassType.ClassName+':'+e.message); on e : EIdException do SNLogger.Log('TClientReader.Execute:EIdException:'+e.ClassType.ClassName+':'+e.message); on e : exception do SNLogger.Log('TClientReader.Execute:Exception:'+e.ClassType.ClassName+':'+e.message); end; end; except on e : exception do begin SNLogger.Log('TClientReader.Execute:'+e.ClassType.ClassName+':'+e.Message); exit; end; end; end; end; |
AW: Indy10: TIdIOHandler.ReadLn hängt Programm auf
So, ich habs nochmal überarbeitet, so scheint das jetzt zu funktionieren:
Delphi-Quellcode:
Mal einen Tag am Stück laufen lassen und schaun obs morgen immernoch läuft.
procedure TClientReader.Execute;
var LReadString : AnsiString; LBuf : TIdBytes; i : Integer; begin while not Terminated do begin sleep(10); try if Assigned(FClient)and Assigned(FClient.IOHandler)and FClient.Connected then begin with FClient.IOHandler do try CheckForDataOnSource(10); if not InputBufferIsEmpty then begin LBuf:=nil; InputBuffer.ExtractToBytes(LBuf); with TStringList.Create do try Text:= BytesToString(LBuf); while Count > 0 do begin LReadString:=Strings[0]; Delete(0); if(Length(Trim(LReadString))>0)then begin if Assigned(FClient.ReaderEvent)then begin FClient.ReaderEvent(LReadString); end; end; end; finally Free; end; end; except on e : EIdClosedSocket do SNLogger.Log('TClientReader.Execute:EIdClosedSocket:'+e.ClassType.ClassName+':'+e.message); on e : EIdReadTimeout do SNLogger.Log('TClientReader.Execute:EIdReadTimeout:'+e.ClassType.ClassName+':'+e.message); on e : EIdException do SNLogger.Log('TClientReader.Execute:EIdException:'+e.ClassType.ClassName+':'+e.message); on e : exception do SNLogger.Log('TClientReader.Execute:Exception:'+e.ClassType.ClassName+':'+e.message); end; end; except on e : exception do begin SNLogger.Log('TClientReader.Execute:'+e.ClassType.ClassName+':'+e.Message); exit; end; end; end; end; Danke plusplus unt Assertor :dp: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:21 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz