Question

I am using Asynchronous TCP server/client communication. I have noticed in my log that the same client reconnects several times. However, it never shows that it was disconnected. My code has logging for both connection and disconnection. So why does readAsync stay in loop while the client has disconnected? Here is the code for your reference:

   private async Task Accept(TcpClient client)
    {
       //get client information 
        string clientEndPoint = GetClientIPAddress(client);          
        log.Info("Client connected at " + clientEndPoint); //same client is connected several times in log

        await Task.Yield (); 

        try 
        {              
            using (client) 
            using (NetworkStream stream = client.GetStream ()) 
            { 
                byte[] dataReceived = new byte [100];                  
                while (await stream.ReadAsync(dataReceived, 0, dataReceived.Length) != 0) //read input stream  -  0=>end of stream is reached
                {                    
                    //pass on data for processing                      
                    var task = ProcessData(dataReceived);   
                }                   
            }
            log.Info("Closing client connection " + clientEndPoint);//this line is never reached in log
            if (client.Connected)
                client.Close();
        } //end try
        catch (Exception ex) 
        {
            log.Error(ex.Message);
            log.Info("Closing client connection " + clientEndPoint);
            if (client.Connected)
                client.Close();
        }
Was it helpful?

Solution

It looks like you may have a half-open problem. You should periodically write data to determine whether the socket is still connected; reads can detect graceful shutdowns but not half-open scenarios.

I describe the half-open problem more on my blog.

OTHER TIPS

Did you check if TCP keep alive is set? That should detect if connection is broken.

Also, check if you got zero length bytes on receive, this means that connection is closed.

Edit: Keep Alive is standard method to check if connection is active, this means that one side sends small chunks of data to the other side periodically: http://en.wikipedia.org/wiki/Keepalive.

Many components have this feature already implemented. I've never used TcpClient class, but it must be some wrapper class for Socket over TCP and, as doc states, this class have exposed underlaying Socket (you can use Socket class for TCP also, but never mind). And this Socket have method SetSocketOption. So try:

client.Socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.KeepAlive, true);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top