Search code examples
c#asynchronoustcpclienttcplistener

using StreamReader during Tcp communication


I'm trying to learn how to implement TCP communication in C# and I am a bit confused about how a StreamReader knows when a sender is no longer sending data.

     private async void TakeCareOfTCPClient(TcpClient paramClient)
    {
        NetworkStream stream = null;
        StreamReader reader = null;

        try
        {
            stream = paramClient.GetStream();
            reader = new StreamReader(stream);

            char[] buff = new char[64];

            while (KeepRunning)
            {
                Debug.WriteLine("*** Ready to read");

                int nRet = await reader.ReadAsync(buff, 0, buff.Length);

                System.Diagnostics.Debug.WriteLine("Returned: " + nRet);

                if (nRet == 0)
                {
                    RemoveClient(paramClient);   //This removes the client from a list containing 
                                                 // all connected clients to the server.

                    System.Diagnostics.Debug.WriteLine("Socket disconnected");
                    break;
                }

                string receivedText = new string(buff);

                System.Diagnostics.Debug.WriteLine("*** RECEIVED: " + receivedText);

                Array.Clear(buff, 0, buff.Length);


            }

        }
        catch (Exception excp)
        {
            RemoveClient(paramClient);
            System.Diagnostics.Debug.WriteLine(excp.ToString());
        }

    }

Let us say that the client sends a message that is exactly 64 characters long. However, the client doesn't disconnect from the server and could send another message at a later time (let's assume a large amount of time passes between messages). Will the Server that has called this method immediately attempt another read and remove the client from its list of connections because the client hasn't sent another message yet (ie 0 characters are read)? On the assumption that it doesn't, what is it about the stream (perhaps a special character it contains or a hidden status it has) that causes the server to wait for another message and not return 0?


Solution

  • So that code is stopping when reader.ReadAsync returns 0.

    The Remarks section of the documentation on Stream.Read holds the key to when that happens:

    Read returns 0 only when there is no more data in the stream and no more is expected (such as a closed socket or end of file).

    So, since the underlying stream is a TCP connection, ReadAsync will return 0 (and TakeCareOfTCPClient will return) when the TCP connection is closed. Either side of the connection can close the connection.