Why disposing NetworkStream disconnects client

Issue

When the following bare bones code is sending or receiving data, the client becomes disconnected.

It was my understanding that a using block disposes the object it creates, ie the NetworkStream object, but why does the TcpClient Socket disconnect?

The console output is…
True
False

class Program
    {
        static void Main(string[] args)
        {
            Console.Title = "Client";

            Process p = Process.Start(@"C:\Users\Teddy\Documents\visual studio 2015\code\TesyingNetworkStream\Server\bin\Debug\server.exe");
            Thread.Sleep(1000);

            IPEndPoint EP = new IPEndPoint(
                    IPAddress.Parse("192.168.1.10"), 4000
                    );

            TcpClient cli = new TcpClient();
            cli.Connect(EP);

            UseClient(cli);

            Console.ReadLine();
            p.Kill();
            p.Close();
        }

        private static void UseClient(TcpClient cli)
        {
            using (NetworkStream ns = cli.GetStream())
            {
                Console.WriteLine(cli.Connected);//True
            }
            Console.WriteLine(cli.Connected);//False
        }
    }

Here is server code if it matters.

class Program2
    {
        static void Main(string[] args)
        {
            Console.Title = "Server";

            TcpListener lis = new TcpListener(
                new IPEndPoint(
                    IPAddress.Any, 4000
                    ));

            lis.Start();

            lis.AcceptTcpClient();

            while (true)
            {
                Thread.Sleep(10);
            }
        }
    }

Solution

Here’s the GetStream() function implementation (from .NET framework source):

public NetworkStream GetStream() {
    if (m_CleanedUp){
        throw new ObjectDisposedException(this.GetType().FullName);
    }
    if (!Client.Connected) {
        throw new InvalidOperationException(SR.GetString(SR.net_notconnected));
    }
    if (m_DataStream == null) {
        m_DataStream = new NetworkStream(Client, true);
    }
    return m_DataStream;
}

Note the true in the call to the NetworkStream constructor. This is the ownsSocket parameter. From MSDN:

If the value of ownsSocket parameter is true, the NetworkStream takes
ownership of the underlying Socket, and calling the Close method also
closes the underlying Socket.

NetworkStream‘s Dispose implementation Close‘s the stream, which then closes the socket.

Answered By – d3dave

Answer Checked By – Pedro (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.