gpt4 book ai didi

windows - 在 Windows 上,WSASend 失败并出现 WSAENOBUFS

转载 作者:可可西里 更新时间:2023-11-01 02:39:41 25 4
gpt4 key购买 nike

在 Windows XP 上,当我在非阻塞套接字上迭代调用 WSASend 时,它因 WSAENOBUFS 而失败。

这里有两个案例:

案例一:

在非阻塞套接字上,我正在调用 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 而失败,并且即使在一段时间后尝试也永远不会恢复,如代码所示。

案例二:

为了解决这个问题,我引用了 this 并按照那里的建议,就在上面的代码之前,我用 SO_SNDBUF 调用了 setsockopt 并将缓冲区大小设置为 0(零)

在这种情况下,WSASend 成功返回了大约 2600 次。然后它失败了。但是等待它再次成功 2600 次然后失败。

现在我在这两种情况下都有这些问题:

案例一:

  1. 什么因素决定了这里的 88000 这个数字?
  2. 如果失败是因为 TCP 缓冲区已满,为什么过了一段时间还没有恢复?

案例二:

  1. 同样,什么因素决定了这里的 2600 数?
  2. 如 Microsoft 知识库文章中所述,如果它直接从应用程序缓冲区发送而不是内部 TCP 缓冲区,为什么它会因 WSAENOBUFS 而失败?

编辑:

在异步套接字的情况下(在 Windows XP 上),行为更奇怪。如果我忽略 WSAENOBUFS 并继续进一步写入套接字,我最终会断开连接 WSAECONNRESET。目前不确定为什么会这样?

最佳答案

这些值是未记录的,取决于您的计算机上安装的可能位于您的应用程序和网络驱动程序之间的内容。它们可能与机器中的内存量有关。在 Vista 及更高版本上,限制(很可能是非页面缓冲池内存和 i/o 页面锁定限制)可能高得多。

处理该问题的最佳方法是在您的协议(protocol)中添加应用程序级流量控制,这样您就不会假设您可以按照您喜欢的任何速率发送。参见 this blog posting有关非阻塞和异步 I/O 如何导致资源使用激增以及除非您有自己的流量控制,否则您如何无法控制它的详细信息。

总而言之,永远不要假设您可以使用非阻塞/异步 API 以您喜欢的速度将数据写入网络。请记住,由于 TCP/IP 的内部流量控制的工作方式,您可能会使用无法控制数量的本地机器资源,并且客户端是唯一可以控制这些资源释放回服务器上 O/S 的速度的东西机器。

关于windows - 在 Windows 上,WSASend 失败并出现 WSAENOBUFS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19608645/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com