C# 为什么套接字在有更多可用字节时读取0字节

C# 为什么套接字在有更多可用字节时读取0字节,c#,.net,sockets,C#,.net,Sockets,我发现以下代码循环的CPU使用率为100%: byte[] buffer = new byte[0x10000]; while (true) { if (socket.Poll (5000000, SelectMode.SelectRead) == false) continue; int available = socket.Available; if (available == 0) return; int read = soc

我发现以下代码循环的CPU使用率为100%:

byte[] buffer = new byte[0x10000];
while (true) {
    if (socket.Poll (5000000, SelectMode.SelectRead) == false)
        continue;
    int available = socket.Available;
    if (available == 0)
        return;
    int read = socket.Receive (buffer);
    Console.WriteLine ("Read: " + read + " Available: " + available);
    /* ... */
}
输出为:

Read: 0 Available: 1
Read: 0 Available: 1
Read: 0 Available: 1
Read: 0 Available: 1
Read: 0 Available: 1
...
我希望socket.Receive方法读取剩余的字节,但它显然不会导致我的代码以100%的速度循环

正如jgauffin所建议的那样:

如果远程主机关闭 与关机的插座连接 方法,并且所有可用数据 已接收,接收方法将 立即完成并返回零 字节

因此,读取0是一种预期,但只有在读取了所有数据之后,才能读取,而套接字。可用声明不是

用于的文档仅提及引发异常的闭合连接

如何确保读取最后一个字节

相关:是如何检测依赖于套接字的已关闭连接的答案。当没有更多数据且连接已关闭时,可用为0,

您阅读了吗

读取0字节表示远程端点已断开连接


使用阻塞套接字或使用异步方法,如
BeginReceive()
。没有必要在.Net中进行
Poll

我发现文档的一部分有点含糊不清,说明断开连接->读取0,不一定相反。关于可用的>0,我应该如何解释?我很久以前就看过文档了。我可以同意,这一点并不十分清楚。您应该始终将
0
视为来自
Receive()
的返回值,无论其他方法/属性如何表示,都应将其视为断开连接。引用MSDN:
如果您处于非阻塞模式,并且协议堆栈缓冲区中没有可用数据,则接收方法将立即完成并抛出SocketException
。我强烈建议您停止在.NET中使用非阻塞套接字。您在这里有一个详细的解释:@zahirdhada:您现在可以了。我认为这是一个bug,当连接关闭时,Available返回0。MS的人可能会发现你的问题并给出正确的答案。您可以做的是尝试发送一些内容,并查看send方法返回的字节数。如果返回0,则连接实际上已关闭。