.net socket问题:客户端与服务器断开连接

时间:2011-07-10 13:35:22

标签: c# .net sockets

在服务器端,我有这个在新线程中运行的代码

static void ListenForConsultant()
    {
        while (true)
        {
            var serverSocket = new TcpListener(IPAddress.Any, 2111);
            serverSocket.Start();
            var clientSocket = serverSocket.AcceptTcpClient();
            consultantConnected = true;
            Console.WriteLine(" >> Consultant Connected");
            byte[] bytesFrom = new byte[10025];
            while (true)
            {
                if (!clientSocket.Connected)
                {
                    break;
                }
                NetworkStream networkStream = clientSocket.GetStream();
                bytesFrom = new byte[10025];
                networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
                var dataFromConsultant = System.Text.Encoding.ASCII.GetString(bytesFrom);
                if (dataFromConsultant.IndexOf("~") != -1 && dataFromConsultant.IndexOf("^") != -1 && dataFromConsultant.IndexOf("^") > dataFromConsultant.IndexOf("~"))
                {
                    var lengthOfMessage = dataFromConsultant.IndexOf("^") - dataFromConsultant.IndexOf("~") - 1;
                    dataFromConsultant = dataFromConsultant.Substring(dataFromConsultant.IndexOf("~") + 1, lengthOfMessage);
                    Console.WriteLine(" >> From consultant:" + dataFromConsultant);
                }

            }

            consultantConnected = false;
            Console.WriteLine(" >> Consultant Disconnected");

            serverSocket.Stop();
        }
    }

我使用putty连接到端口2111.一切正常,但是当我关闭putty socket没有关闭时,我有条件

if (!clientSocket.Connected)
{
      break;
}

Debug告诉我,即使我从服务器断开连接,clientSocket.Connected也是如此。

为什么会这样?

1 个答案:

答案 0 :(得分:2)

tcpClient.Connected属性值不可靠,它的值取决于上次通信;因此,如果最后一次通信成功,则它的值为true,否则为false。有关该支票的更多信息this

使用此IsConnected属性检查tcpClient是否已连接:

public static bool IsConnected
{
    get
    {
        try
        {
            //return _tcpClient != null && _tcpClient.Client != null && _tcpClient.Client.Connected;

            if (_tcpClient != null && _tcpClient.Client != null && _tcpClient.Client.Connected)
            {

                /* As the documentation:
                    * When passing SelectMode.SelectRead as a parameter to the Poll method it will return 
                    * -either- true if Socket.Listen(Int32) has been called and a connection is pending;
                    * -or- true if data is available for reading; 
                    * -or- true if the connection has been closed, reset, or terminated; 
                    * otherwise, returns false
                    */

                // Detect if client disconnected
                if (_tcpClient.Client.Poll(0, SelectMode.SelectRead))
                {
                    byte[] buff = new byte[1];
                    if (_tcpClient.Client.Receive(buff, SocketFlags.Peek) == 0)
                    {
                        // Client disconnected
                        return false;
                    }
                    else
                    {
                        return true;
                    }
                }

                return true;
            }
            else
            {
                return false;
            }
        }
        catch
        {
            return false;
        }
    }
}

修改:请注意,检查后IsConnected检查不会阻止其断开连接。即,在IsConnected检查评估并返回true之后,套接字在连接之后就可以断开连接,所以你应该将所有通信包装在try/catchtry/catch/finally块预期中要随时断开的套接字。