Instantly detect client disconnection from server socket [.net]


Answers

This is simply not possible. There is no physical connection between you and the server (except in the extremely rare case where you are connecting between two compuers with a loopback cable).

When the connection is closed gracefully, the other side is notified. But if the connection is disconnected some other way (say the users connection is dropped) then the server won't know until it times out (or tries to write to the connection and the ack times out). That's just the way TCP works and you have to live with it.

Therefore, "instantly" is unrealistic. The best you can do is within the timeout period, which depends on the platform the code is running on.

EDIT: If you are only looking for graceful connections, then why not just send a "DISCONNECT" command to the server from your client?

Question

How can I detect that a client has disconnected from my server?

I have the following code in my AcceptCallBack method

static Socket handler = null;
public static void AcceptCallback(IAsyncResult ar)
{
  //Accept incoming connection
  Socket listener = (Socket)ar.AsyncState;
  handler = listener.EndAccept(ar);
}

I need to find a way to discover as soon as possible that the client has disconnected from the handler Socket.

I've tried:

  1. handler.Available;
  2. handler.Send(new byte[1], 0, SocketFlags.None);
  3. handler.Receive(new byte[1], 0, SocketFlags.None);

The above approaches work when you are connecting to a server and want to detect when the server disconnects but they do not work when you are the server and want to detect client disconnection.

Any help will be appreciated.




C# Socket - How to check if Client disconnects

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 😛




How to detect disconnected state of TCP Socket

Using code like

 'if(socket.Connected) { socket.Write(...) }

creates a race condition. You're better off just calling socket.Write and handling the exceptions and/or disconnections.

Socket layer shall managed using exceptions. The IOException thrown has the inner exception set to a SocketException, which contains all information required to detect timeouts or closed sockets remotely




This is simply not possible. There is no physical connection between you and the server (except in the extremely rare case where you are connecting between two compuers with a loopback cable).

When the connection is closed gracefully, the other side is notified. But if the connection is disconnected some other way (say the users connection is dropped) then the server won't know until it times out (or tries to write to the connection and the ack times out). That's just the way TCP works and you have to live with it.

Therefore, "instantly" is unrealistic. The best you can do is within the timeout period, which depends on the platform the code is running on.

EDIT: If you are only looking for graceful connections, then why not just send a "DISCONNECT" command to the server from your client?