TCP通信 - 异步读取循环不会结束

时间:2014-04-08 04:16:12

标签: c# asynchronous tcpclient

我正在使用异步TCP服务器/客户端通信。我在日志中注意到同一个客户端多次重新连接。但是,它从未表明它已断开连接。我的代码记录了连接和断开连接。那么为什么readAsync在客户端断开连接时保持循环?以下是供您参考的代码:

   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();
        }

2 个答案:

答案 0 :(得分:2)

看起来你可能有一个半开放的问题。您应该定期写入数据以确定套接字是否仍然连接;读取可以检测到正常关闭,但不能检测半开放场景。

我在博客上更多地描述了half-open problem

答案 1 :(得分:0)

您是否检查过TCP keep alive是否已设定?这应该检测连接是否被破坏。

另外,检查接收时是否有零长度字节,这意味着连接已关闭。

编辑:Keep Alive是检查连接是否处于活动状态的标准方法,这意味着一方定期向另一方发送小块数据:http://en.wikipedia.org/wiki/Keepalive

许多组件已经实现了此功能。我从来没有使用TcpClient类,但它必须是Socket通过TCP的一些包装类,并且正如doc所说,这个类暴露了底层Socket(你可以使用{{1 } Socket的类也是,但没关系)。这个TCP有方法Socket。所以试试:

SetSocketOption