Correct way to detect a client has disconnected fr

2020-07-22 17:27发布

问题:

I have used a Asynchronous TCP/IP server, everything works fine but when a client disconnects due to error or forced exit of the application it also closes my server due to an exception of type IO.IOException. The exception occurs in the following sub:

   Private Sub ReadCallback(ByVal result As IAsyncResult)
        Try


            Dim client As Client = TryCast(result.AsyncState, Client)
            If client Is Nothing Then
                Return
            End If
            'MsgBox(client.ClientID)
            Dim networkStream As NetworkStream = client.NetworkStream
            Dim read As Integer = networkStream.EndRead(result) **' ERRORS HERE!**
            If read = 0 Then
            Dim client As Client = TryCast(result.AsyncState, Client)
            SyncLock Me.Clients
                Me.Clients.Remove(Client.ClientID)
                Return
            End SyncLock
            End If

The below code throws an IO.IOException when a client disconnects from my TCP Server:

Dim read As Integer = networkStream.EndRead(result) **' ERRORS HERE!**

Other then catching the IO.IOException how can I prevent this from creating the exception in the first place. Basically I'd like to remove my client when this scenario occurs, at the moment as a work around I have removed the client on an IO.IOException and rethrown the method. Would rather a better method.

回答1:

The exception is the way. There is no TCP API or callback that tells you about broken connections. You have to read or write to find out. This was designed deep into TCP for reliability reasons.



回答2:

Hope this helps :

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    IAsyncResult result = socket.BeginConnect(_ip, Port, null, null);
    bool success = result.AsyncWaitHandle.WaitOne(500, true); // 500 is milisecods to wait
     if (socket.Connected && socket.IsBound && success)
     {
          // do your work                          
     }else
    {
     // open a new connection or show your message to user
    }