Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Indy 9 TCP server doesn't recognize client disconnection

611 views
Skip to first unread message

Amit Zohar

unread,
Feb 23, 2005, 3:24:39 AM2/23/05
to
Hi.
I'm using a TIdTcpServer. When the client connects I open an TIdPeerThread.
The tread works fine and can disconnect the socket (from the server side),
but when the client disconnects there is no property or exception that
detects this. I tried connection.connected, connection.socket.connected,
connection.closedgracefully.
Please advice, Amit.


Remy Lebeau (TeamB)

unread,
Feb 23, 2005, 4:56:03 AM2/23/05
to

"Amit Zohar" <am...@roseman.co.il> wrote in message
news:421c...@newsgroups.borland.com...

> I'm using a TIdTcpServer. When the client connects I open an
> TIdPeerThread. The tread works fine and can disconnect the
> socket (from the server side), but when the client disconnects
> there is no property or exception that detects this.

Yes, there is, assuming the socket disconnected gracefully in the first
place, that is. An exception is thrown the next time you try to access the
socket after the disconnect. If the socket was not disconnected gracefully,
however, then there is usually no way to detect the disconnect for a long
time, until the socket times out internally. That is just the way sockets
are implemented in general. The only thing you can do in that situation is
implement your own timeouts in your code, and assume the socket is gone if
nothing happens for a period of time.


Gambit


Amit Zohar

unread,
Feb 24, 2005, 5:54:16 AM2/24/05
to
Hi again.
This is very disappointing, because in TServerSocket which is a former TCP
component that was replaced by Indy, when the client disconnected the socket
you would get an event that indicates this. I would expect Indy's
connection.connected to indicate this like any other disconnection, since
the client is no longer there, and probably any attempt to send something to
the socket will fail. So why not inform this the simplest way?
Regards, Amit.

"Remy Lebeau (TeamB)" <no....@no.spam.com> wrote in message
news:421c5337$1...@newsgroups.borland.com...

Martin James

unread,
Feb 24, 2005, 8:17:20 AM2/24/05
to

"Amit Zohar" <am...@roseman.co.il> wrote in message
news:421d...@newsgroups.borland.com...

> Hi again.
> This is very disappointing, because in TServerSocket which is a former TCP
> component that was replaced by Indy, when the client disconnected the
socket
> you would get an event that indicates this. I would expect Indy's
> connection.connected to indicate this like any other disconnection, since
> the client is no longer there, and probably any attempt to send something
to
> the socket will fail. So why not inform this the simplest way?
> Regards, Amit.
>

I suspect that you misunderstand what Remy is saying.

If, say, you have a server thread that is continualy making a blocking read
from the socket, an exception will occur if the server<> client socket is
disconnected by the client in a managed fashion. This is detectable
because of the TCP protocol exchange that takes place when a client actively
disconnects. So, if you have a continual read on the socket, the
EidConnClosedGracefully exception will be generated by this read as soon as
the disconnect protocol-exchange with the client is complete.

Remy is saying that no notification from TCP is possible if a client becomes
*unreachable* without some attempt at exchanging data that allows TCP to
time out the data transfer. TserverSocket cannot do this either, nor can
ICS or any socket component. With an awesomely complex & ever-changing
internetwork between them, it is not sensibly possible to detect when the
number of viable routes between a TCP client & server has dropped to zero
without trying to send a packet from one to the other. To obtain prompt-ish
notification of unreachability, you have to implement an application-level
poll.

Rgds.,
Martin


Remy Lebeau (TeamB)

unread,
Feb 24, 2005, 2:26:40 PM2/24/05
to

"Amit Zohar" <am...@roseman.co.il> wrote in message
news:421d...@newsgroups.borland.com...

> This is very disappointing

Only because you do not understand what is actually happening.

> in TServerSocket ..., when the client disconnected the socket


> you would get an event that indicates this.

Only in non-blocking mode. In blocking mode, it is the worker thread's
responsibility to detect the disconnect, there is no event triggered for it.

TIdTCPServer does have an OnDisconnect event that is triggered whenever a
worker thread terminates.

> I would expect Indy's connection.connected to indicate this like
> any other disconnection

It does.

> since the client is no longer there, and probably any attempt
> to send something to the socket will fail.

Exactly. That is the only way to detect a disconnect in a blocking socket.

> So why not inform this the simplest way?

You are not taking into account that Indy uses blocking sockets, and
blocking sockets need to access the socket before detecting errors and
disconnects. There are no asynchronous notifications issued like with
non-blocking sockets. Even TServerSocket in blocking mode also has to
access the socket in order to detect errors and disconnects. These are
issues to general socket programming, they are not bugs specific to Indy.
You also need to take into account what I said earlier - if the socket is
not disconnected gracefully, then there is no way to know for awhile that
the socket is no longer available, unless you implement your own manual
timeouts. The underlying socket stack itself (WinSock, Libc, etc) has no
way of knowing when a socket has been disconnected abnormally, so it has to
time out internally before errors are reported on lost sockets, and those
timeouts are usually set to hours by default.


Gambit


0 new messages