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