-1

I'm making a little program, and I'm trying to handle a Client disconnect. When the client disconnects he sends a shutdown message and I handle that. But when the client gets closed with force (network connection lost, task killed, exception..) The server still sees the client as connected. Now, I'm trying to Immediately update this information, once the client is not connected anymore he should be removed. I can't just ping him every now and then, can I? What if there is a transmission ongoing and I interfer with my ping command?

TL;DRHow do I know if my client is not connected anymore?

mrousavy
  • 241
  • 2
  • 12
  • TCP is _designed_ to prevent you from detecting many types of disconnect. Other than a graceful closure, only if the remote endpoint has forcefully closed the socket will you get an error, and even then only if you have a read pending on the socket. Otherwise, errors are not detected unless you write to the socket. Note that TCP includes a "keep-alive" option that periodically will write to the socket, and so can perform this automatically. Note also that trying to detect disconnections is generally **a bad idea**, because it negates the whole point of the fault-tolerance of TCP. – Peter Duniho Oct 09 '16 at 00:11
  • See the marked duplicate for a more in-depth discussion of the question. – Peter Duniho Oct 09 '16 at 00:11

2 Answers2

0

When the socket is gracefully shutdown you will receive the shutdown message (A return of zero bytes from a read attempt)... good times!

If the remote task is killed and the socket is not gracefully shutdown (or some other scenario where the client is gone but the server is still listening) you have a "half open socket". Detecting these can be tricky depending on the scenario. TCP has a keep-alive mechanism which should detect this (mainly on non-mobile networks and if they're enabled). For mobile connections (Specifically flakey GPRS/Edge) you will find that even keep-alives don't always work and any attempt to send data just returns success. In this scenario you should base a valid connection on an automatic timeout if the client hasn't sent any data to you... of course there are always the situations where the client attempts to re-connect but you appear to already have a socket sitting there

Scott Perham
  • 2,125
  • 1
  • 7
  • 18
0

Try this. It works for me.

private static bool IsSocketConnected(Socket socket)
{
    try
    {
        return !(socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0);
    }
    catch (SocketException) { return false; }
}
  • This also returns true if there is no data available for reading but the sockets are still connected as far as I know. That's not what I want exactly.. But thanks! – mrousavy Oct 08 '16 at 15:16