Instantly detect client disconnection from server socket

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.


    Since there are no events available to signal when the socket is disconnected, you will have to poll it at a frequency that is acceptable to you.

    Using this extension method, you can have a reliable method to detect if a socket is disconnected.

    static class SocketExtensions
    {
      public static bool IsConnected(this Socket socket)
      {
        try
        {
          return !(socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0);
        }
        catch (SocketException) { return false; }
      }
    }
    

    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?


    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. The keepAliveInterval parameter specifies the interval, in milliseconds, between when successive keep-alive packets are sent if no acknowledgement is received.

        void SetKeepAlive(bool on, uint keepAliveTime , uint keepAliveInterval )
        {
            int size = Marshal.SizeOf(new uint());
    
            var inOptionValues = new byte[size * 3];
    
            BitConverter.GetBytes((uint)(on ? 1 : 0)).CopyTo(inOptionValues, 0);
            BitConverter.GetBytes((uint)time).CopyTo(inOptionValues, size);
            BitConverter.GetBytes((uint)interval).CopyTo(inOptionValues, size * 2);
    
            socket.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null);
        }
    

    I'm also using synchronous reading:

    socket.BeginReceive(packet.dataBuffer, 0, 128,
                        SocketFlags.None, new AsyncCallback(OnDataReceived), packet);
    

    And in callback, here is caught timeout SocketException , which raises when socket doesn't get ACK signal after keep-alive packet.

    public void OnDataReceived(IAsyncResult asyn)
    {
        try
        {
            SocketPacket theSockId = (SocketPacket)asyn.AsyncState;
    
            int iRx = socket.EndReceive(asyn);
        catch (SocketException ex)
        {
            SocketExceptionCaught(ex);
        }
    }
    

    This way, I'm able to safely detect disconnection between TCP client and server.

    链接地址: http://www.djcxy.com/p/56564.html

    上一篇: 使用DataOutputStream发送一个0字节?

    下一篇: 立即检测客户端与服务器套接字的连接