为什么配置 NetworkStream 会断开客户端
Why disposing NetworkStream disconnects client
当以下基本代码发送或接收数据时,客户端断开连接。
据我了解,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);
}
}
}
这是因为 cli.GetStream();
不会在您每次调用它时都创建一个新流,连接只有一个流,并且每次调用 cli.GetStream();
returns 相同的流目的。当您处理向 TcpClient 发送信号的共享流时,您已完成并标记 TcpClient 已断开连接。
这是 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;
}
请注意 NetworkStream
构造函数调用中的 true
。这是 ownsSocket
参数。来自 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
的 Dispose
实现 Close
的流,然后关闭套接字。
当以下基本代码发送或接收数据时,客户端断开连接。
据我了解,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);
}
}
}
这是因为 cli.GetStream();
不会在您每次调用它时都创建一个新流,连接只有一个流,并且每次调用 cli.GetStream();
returns 相同的流目的。当您处理向 TcpClient 发送信号的共享流时,您已完成并标记 TcpClient 已断开连接。
这是 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;
}
请注意 NetworkStream
构造函数调用中的 true
。这是 ownsSocket
参数。来自 MSDN:
If the value of
ownsSocket
parameter istrue
, the NetworkStream takes ownership of the underlying Socket, and calling theClose
method also closes the underlying Socket.
NetworkStream
的 Dispose
实现 Close
的流,然后关闭套接字。