Problems closing TcpClient and NetworkStream

I am currently working on a simple chat client program (I wanted to get information about connections to the client server in C #). It still works, except to disconnect from the server correctly.

On the client, I use this code here to close the connection:

client.Client.Disconnect(false); // client is the TcpClient
client.Close();

There is a chain on the server with a chain waiting for messages from the client:

private void StartChat()
{
    int requestCount = 0;
    byte[] bytesFrom = new byte[10025];
    string dataFromClient = null;
    string rCount = null;

    while (true)
    {
        try
        {
            requestCount++;

            NetworkStream stream = tcpClient.GetStream();

            int bufferSize = (int)tcpClient.ReceiveBufferSize;
            if (bufferSize > bytesFrom.Length)
            {
                bufferSize = bytesFrom.Length;
            }

            stream.Read(bytesFrom, 0, bufferSize);
            dataFromClient = System.Text.Encoding.UTF8.GetString(bytesFrom);
            dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
            rCount = Convert.ToString(requestCount);

            string message = client.Name + " says: " + dataFromClient;
            program.Broadcast(message);

        }
        catch(Exception ex) when (ex is ObjectDisposedException || ex is InvalidOperationException || ex is System.IO.IOException)
        { 
            program.UserDisconnected(client);
            break;
        }
        catch(ArgumentOutOfRangeException ex)
        {
            Debug.WriteLine(ex.ToString());
            break;
        }
        catch(Exception ex)
        {
            Debug.WriteLine(ex.ToString());
            break;
        }
    }

If the client disconnects with the code shown above, the function constantly extracts the stream and produces the following output:

\0\0\0\0\0\0\0 [and so on]

In this case, it ArgumentOutOfRangeExceptionwill be selected because there is no index $. I added breakto avoid looping endlessly.

, ObjectDisposedException . , System.IO.IOException , , , .

, , , , , .

, , ? , ?

!

Update:

private void StartChat()
{
    int requestCount = 0;
    byte[] bytesFrom = new byte[10025];
    string dataFromClient = null;
    string rCount = null;

    while (true)
    {
        try
        {
            requestCount++;

            NetworkStream stream = tcpClient.GetStream();
            stream.ReadTimeout = 4000;

            int bufferSize = (int)tcpClient.ReceiveBufferSize;
            if (bufferSize > bytesFrom.Length)
            {
                bufferSize = bytesFrom.Length;
            }


            // Wait for a client message. If no message is recieved within the ReadTimeout a IOException will be thrown
            try
            {
                int bytesRead = stream.Read(bytesFrom, 0, bufferSize);
                stream.Flush();

                if (bytesRead == 0)
                {
                    throw new System.IO.IOException("Connection seems to be refused or closed.");
                }
            }
            catch (System.IO.IOException)
            {
                byte[] ping = System.Text.Encoding.UTF8.GetBytes("%");
                stream.WriteTimeout = 1;

                stream.Write(ping, 0, ping.Length);
                continue;
            }


            dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
            dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
            rCount = Convert.ToString(requestCount);

            string message = client.Name + " says: " + dataFromClient;
            program.Broadcast(message);

        }
        catch(Exception ex) when (ex is ObjectDisposedException || ex is InvalidOperationException || ex is System.IO.IOException)
        {
            Debug.WriteLine(ex.ToString());
            program.UserDisconnected(client);
            break;
        }
        catch(ArgumentOutOfRangeException ex)
        {
            Debug.WriteLine(ex.ToString());
        }
        catch(Exception ex)
        {
            Debug.WriteLine(ex.ToString());
            break;
        }
    }
}
+4
2

stream.Read - .

0, , , .

int bytes = stream.Read(bytesFrom, 0, bufferSize);
if (bytes == 0)
{
    // client has disconnected
    break;
}

dataFromClient = System.Text.Encoding.UTF8.GetString(bytesFrom, 0, bytes);

, :

  • 0
  • - ,
  • "", .

, , , , , . / keep-alive.

+3

int bytesRead = stream.Read(...); if (bytesRead == 0)// disconneted

+1

All Articles