takayoshi
takayoshi

Reputation: 2799

.net socket problem: client disconnect from server

On server side I have this code which running in new thread

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

I connect using putty to port 2111. All works ok, but when I close putty socket doesn't close, however I have condition

if (!clientSocket.Connected)
{
      break;
}

Debug shows me that clientSocket.Connected is true even after I disconnected from server.

Why does this happen?

Upvotes: 1

Views: 1513

Answers (1)

Jalal Said
Jalal Said

Reputation: 16162

The tcpClient.Connected property value is not reliable, it's value depending on the last communication; so if the last communication were succeed then it's value is true otherwise it is false. for more information on that check this.

Use this IsConnected property to check if the tcpClient is connected:

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

Edit: Note that checking IsConnected will not prevents it from disconnect after the check. i.e its possible to happen that the socket is disconnected just after it was connected "after the IsConnected check evaluated and return true", So you should wrap all communication in try/catch or try/catch/finally block expecting the socket to be disconnected at any time.

Upvotes: 2

Related Questions