为什么 TCP 端点断开连接会在另一个端点上抛出一堆 0 字节?

Why does TCP endpoint disconnection throws a bunch of 0 bytes on the other endpoint?

我在 C# 中玩弄套接字和 TCP,这发生了。当连接的一个端点断开连接时,另一个端点在使用 Receive 方法时会得到一堆零字节。为什么会这样?

这是可以重现我提到的内容的代码(运行 with dotnet script):

using System;
using System.Net;
using System.Net.Sockets;
                    
Socket s = new Socket(SocketType.Stream, ProtocolType.Tcp);
s.Bind(new IPEndPoint(IPAddress.Any, 1000));
s.Listen(1);
Console.WriteLine("Opened.");

Socket c = new Socket(SocketType.Stream, ProtocolType.Tcp);
c.Connect(new IPEndPoint(IPAddress.Loopback, 1000));

Socket i = s.Accept();
Console.WriteLine("Accepted.");

byte[] buffer = Array.Empty<byte>();

i.Shutdown(SocketShutdown.Both);

while (true)
{
    buffer = new byte[4];
    c.Receive(buffer, 4, SocketFlags.None);
    Console.WriteLine(BitConverter.ToString(buffer).Replace("-"," "));
}

当问题发生时,控制台会打印很多00 00 00 00序列。它也发生在 ic 交换的情况下。

... the other when using Receive method gets a bunch of zero bytes

由于错误的代码,这是错误的解释。打印出来的是原来的零初始化缓冲区的内容。缓冲区在 c.Receive 内没有变化,因为调用没有收到任何东西。

应该做的是检查 return value of Receive 这是实际读取的字节数。它会显示没有代码 returned。相反,它只是简单但错误地假设读取了 4 个字节,因为需要 4 个字节。

一般来说 Receive 总是可以 return 比要求的少字节,不仅仅是在连接关闭时。因此,只有 buffer 中的字节数应被视为从对等方读取的字节数与 Receive.[=17 收到的 字节数 显式 returned 一样多=]