Почему утилита NetworkStream отключает клиента

Когда следующий голый код отправляет или получает данные, клиент отключается.

Насколько я понимаю, блок using удаляет созданный им объект, то есть объект NetworkStream, но почему разъединение TcpClient Socket отключается?

Консольный вывод... 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
        }
    }

Вот код сервера, если это имеет значение.

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

2 ответа

Решение

Вот GetStream() Реализация функции (из источника.NET Framework):

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

Обратите внимание true в призыве к NetworkStream конструктор. Это ownsSocket параметр. Из MSDN:

Если значение ownsSocket параметр trueNetworkStream становится владельцем основного сокета и вызывает Close Метод также закрывает основной сокет.

NetworkStream"s Dispose реализация CloseЭто поток, который затем закрывает сокет.

Это потому что cli.GetStream(); не создает новый поток каждый раз, когда вы вызываете его, существует отдельный поток для соединения и каждый вызов cli.GetStream(); возвращает тот же объект потока. Когда вы избавляетесь от этого общего потока, который сигнализирует TcpClient, все готово, и он отмечает, что TcpClient отключен.

Другие вопросы по тегам