Instantly detect client disconnection from server socket

后端 未结 14 1697
北恋
北恋 2020-11-22 09:27

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

I have the following code in my AcceptCallBack method

static Socket hand         


        
14条回答
  •  梦谈多话
    2020-11-22 09:37

    Expanding on comments by mbargiel and mycelo on the accepted answer, the following can be used with a non-blocking socket on the server end to inform whether the client has shut down.

    This approach does not suffer the race condition that affects the Poll method in the accepted answer.

    // Determines whether the remote end has called Shutdown
    public bool HasRemoteEndShutDown
    {
        get
        {
            try
            {
                int bytesRead = socket.Receive(new byte[1], SocketFlags.Peek);
    
                if (bytesRead == 0)
                    return true;
            }
            catch
            {
                // For a non-blocking socket, a SocketException with 
                // code 10035 (WSAEWOULDBLOCK) indicates no data available.
            }
    
            return false;
        }
    }
    

    The approach is based on the fact that the Socket.Receive method returns zero immediately after the remote end shuts down its socket and we've read all of the data from it. From Socket.Receive documentation:

    If the remote host shuts down the Socket connection with the Shutdown method, and all available data has been received, the Receive method will complete immediately and return zero bytes.

    If you are in non-blocking mode, and there is no data available in the protocol stack buffer, the Receive method will complete immediately and throw a SocketException.

    The second point explains the need for the try-catch.

    Use of the SocketFlags.Peek flag leaves any received data untouched for a separate receive mechanism to read.

    The above will work with a blocking socket as well, but be aware that the code will block on the Receive call (until data is received or the receive timeout elapses, again resulting in a SocketException).

提交回复
热议问题