为啥处理 NetworkStream 会断开客户端
Posted
技术标签:
【中文标题】为啥处理 NetworkStream 会断开客户端【英文标题】:Why disposing NetworkStream disconnects client为什么处理 NetworkStream 会断开客户端 【发布时间】:2017-01-25 16:06:36 【问题描述】:当以下基本代码发送或接收数据时,客户端断开连接。
我的理解是 using 块会释放它创建的对象,即 NetworkStream 对象,但为什么 TcpClient Socket 会断开连接?
控制台输出是... 真的 假的
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);
【问题讨论】:
【参考方案1】:这是GetStream()
函数实现(来自.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;
注意true
在对NetworkStream
构造函数的调用中。这是ownsSocket
参数。来自MSDN:
如果
ownsSocket
参数的值为true
,则NetworkStream取 底层 Socket 的所有权,并调用Close
方法 关闭底层 Socket。
NetworkStream
的 Dispose
实现 Close
的流,然后关闭套接字。
【讨论】:
【参考方案2】:这是因为cli.GetStream();
不会在您每次调用它时都创建一个新流,所以连接只有一个流,并且每次调用cli.GetStream();
都会返回相同的流对象。当您处理向 TcpClient 发出信号的共享流时,您就完成了,它标志着 TcpClient 已断开连接。
【讨论】:
以上是关于为啥处理 NetworkStream 会断开客户端的主要内容,如果未能解决你的问题,请参考以下文章
为啥当客户端断开连接时这个简单的 websocket 代码会抛出?
XMPP 流发送,不接收。为啥 XMPP 流可能会断开连接?