|Subject:||Indy10 - TIdTCPConnection, Open/Close, ReadLnTimedOut, Read Thread|
|Posted by:||Michael Stieler (michael.stiel…@rie.eu)|
|Date:||Tue, 27 Mar 2007|
a write an application that has to handle multiple TCP Connections.
Two of them have sort of a telnet protocol, the others are binary.
For each connection I create an "Object" inherited from TComponent, in
which the connection is initialized as follows:
conn := TIdTcpConnection.Create(self);
conn.Socket.OnStatus := TcpStatus;
The telnet sort connection is a Command+Response system. Because of
problems I had with the IdTelnetClient, I also use the IdTcpConnection
class here (Linefeed is LF+CR for one response, the others CR+LF)
Executing a command works like that:
A := conn.Socket.ReadLn(CR+LF);
This works for 99% of the commands, and then I get a Timeout in the
ReadLn. And I even get it when I set the ReadTimeout up to 2500ms,
comparing to a TCP Terminal program this can't be the Server's fault,
there the response is always at once received. It seems to get worse
when talking to two Servers, although I call ReadLn sequentially. I put
the periodically execution of the commands in a TThread so the main
application doesn't freeze, but what could it be that I get those
ReadLnTimeOuts so often?
Is my method of connecting/disconnecting right?
If (conn.Socket.Opened) then conn.Socket.Close;
(The protocol is very time critical, I assumed this returns faster than
using no write buffer)
(Data left in InputBuffer could make the connection look like open)
I experimented with Disconnect; and Connect; and so on but the
Open/Close methods of the Socket seemed to be most direct to me.
For the binary data connections I created a TReadThread =
Class(TThread), that is created when connection is opened, and
terminated/freed when connection is closed.
Sometimes it occurs, that the thread doesn't terminate. I close the
connection as follows:
if readThread <> nil then begin
// Between here..
// and here the program freezes in CsrNewThread of a System DLL
The thread is as easy as this (without exception handling):
while (Not Terminated) and conn.Socket.Opened do begin
With conn.Socket do begin
If not Opened then break;
I := InputBuffer.Size;
If I>0 then begin
S := ReadString(I);
If Assigned( FOnRead ) then
FonRead(conn, S); // Not Synchronized read event
One time it happened, the tracer showed me the program was in
CheckForDataSource() method. Is it possible that this methode doesn't
return? I read about this method is not thread safe. I don't access
buffer or read functions during the run-time of this thread.
Indy-Version is the Dev-Snapshot from Fulgan.com
Thanks for your help..