Почему утилита 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
параметрtrue
NetworkStream становится владельцем основного сокета и вызываетClose
Метод также закрывает основной сокет.
NetworkStream
"s Dispose
реализация Close
Это поток, который затем закрывает сокет.
Это потому что cli.GetStream();
не создает новый поток каждый раз, когда вы вызываете его, существует отдельный поток для соединения и каждый вызов cli.GetStream();
возвращает тот же объект потока. Когда вы избавляетесь от этого общего потока, который сигнализирует TcpClient, все готово, и он отмечает, что TcpClient отключен.