在 Windows XP 上,当我在非阻塞套接字上的迭代中调用WSASend时,它会因 WSAENOBUFS 而失败。
我这里有两个案例:
情况1:
在非阻塞套接字上,我正在调用WSASend。这是伪代码:
while(1)
{
result = WSASend(...); // Buffersize 1024 bytes
if (result == -1)
{
if (WSAGetLastError() == WSAENOBUFS)
{
// Wait for some time before calling WSASend again
Sleep(1000);
}
}
}
在这种情况下,WSASend 成功返回大约 88000 次。然后它会因 WSAENOBUFS 而失败,即使在经过一段时间尝试后也不会恢复,如代码所示。
案例二:
为了解决这个问题,我参考了这个并按照那里的建议,就在上面的代码之前,我用 SO_SNDBUF调用了setsockopt并将缓冲区大小设置为 0(零)
在这种情况下,WSASend 成功返回大约 2600 次。然后它失败了。但是在等待它再次成功 2600 次之后,它又失败了。
现在我在这两种情况下都有这些问题:
情况1:
- 是什么因素决定了这个数字88000?
- 如果失败是因为 TCP 缓冲区已满,为什么一段时间后它没有恢复?
案例二:
- 同样,是什么因素决定了这里的数字 2600?
- 如 Microsoft 知识库文章中所述,如果它直接从应用程序缓冲区发送内部 TCP 缓冲区而不是内部 TCP 缓冲区,为什么它会因 WSAENOBUFS 而失败?
编辑:
在异步套接字的情况下(在 Windows XP 上),行为更奇怪。如果我忽略 WSAENOBUFS 并继续进一步写入套接字,我最终会断开 WSAECONNRESET。目前不确定为什么会发生这种情况?