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:
handler.Available;
handler.Send(new byte[1], 0, SocketFlags.None);
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.
The example code here http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.connected.aspx shows how to determine whether the Socket is still connected without sending any data.
If you called Socket.BeginReceive() on the server program and then the client closed the connection "gracefully", your receive callback will be called and EndReceive() will return 0 bytes. These 0 bytes mean that the client "may" have disconnected. You can then use the technique shown in the MSDN example code to determine for sure whether the connection was closed.
Using the method SetSocketOption, you will be able to set KeepAlive that will let you know whenever a Socket gets disconnected
http://msdn.microsoft.com/en-us/library/1011kecd(v=VS.90).aspx
Hope it helps! Ramiro Rinaldi
i had same problem , try this :
Someone mentioned keepAlive capability of TCP Socket. Here it is nicely described:
http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html
I'm using it this way: after the socket is connected, I'm calling this function, which sets keepAlive on. The
keepAliveTime
parameter specifies the timeout, in milliseconds, with no activity until the first keep-alive packet is sent. ThekeepAliveInterval
parameter specifies the interval, in milliseconds, between when successive keep-alive packets are sent if no acknowledgement is received.I'm also using synchronous reading:
And in callback, here is caught timeout
SocketException
, which raises when socket doesn't get ACK signal after keep-alive packet.This way, I'm able to safely detect disconnection between TCP client and server.
I've found quite useful, another workaround for that!
If you use asynchronous methods for reading data from the network socket (I mean, use
BeginReceive
-EndReceive
methods), whenever a connection is terminated; one of these situations appear: Either a message is sent with no data (you can see it withSocket.Available
- even thoughBeginReceive
is triggered, its value will be zero) orSocket.Connected
value becomes false in this call (don't try to useEndReceive
then).I'm posting the function I used, I think you can see what I meant from it better:
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?