.net socket проблема: клиент отключается от сервера - PullRequest
1 голос
/ 10 июля 2011

На стороне сервера у меня есть этот код, который работает в новом потоке

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

Я использую замазку для порта 2111. Все работает нормально, но когда я закрываю, замазка не закрывается, однако у меня есть условие

if (!clientSocket.Connected)
{
      break;
}

Отладка показывает мне, что clientSocket.Connected имеет значение true, даже после того, как я отключился от сервера.

Почему это происходит?

1 Ответ

2 голосов
/ 10 июля 2011

Значение свойства 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, оцененной и вернувшей истину», поэтому вы должны обернуть все коммуникации в блок try/catch или try/catch/finally, ожидая, что сокет будет отключен вв любое время.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...