无法在套接字上执行操作,因为系统缺少足够的缓冲区 space 或因为队列已满

operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full

我有一台机器 运行 多个不断执行 UNC 访问的应用程序 (\server-ip\share) 所以:

std::ifstream src(fileName, std::ios::binary);
std::ofstream dst(newFileName, std::ios::binary);
CopyFromRemote(ifstream &src, ofstream &dst);
dst.flush();
dst.close();
src.close();

void CopyFromRemote(ifstream src, ofstream dst)
{
  char buffer[8192]; // read 8KB each chunk
  while (src.read(buffer, sizeof(buffer)))
  {
    dst.write(buffer, sizeof(buffer));
    // Here there is code that checks that some timer !> max read time so as 
    // to not be stuck if there is network issue with this src.
  }
  if (src.eof() && src.gcount() > 0)
  {
    dst.write(buffer, src.gcount()); // few bytes left
  }
}

可以看出,每 8KB(文件大几 MB)都要遍历网络,网络非常紧张。这里的好处是能够在从特定来源花费太长时间的情况下中止文件复制。

我面临的问题是几天后所有 UNC 都无法从这台机器访问并出现上述错误。我不确定问题的根源是什么,但它是零星的并且很难确定。当问题发生时,第一行失败(std::ifstream src ...)。 telnet 也停止工作。

此外:当终止应用程序时,可以再次访问 UNC。重新启动进程时,UNC 立即无法再次访问。重启机器解决了好几天的问题

最初我以为是Port exhaustion,但netstat并没有显示太多连接或挂起连接,任务管理器性能选项卡也没有显示异常数字。 TcpQry 显示正常 TCP/UDP 映射数字。

另外:当问题发生时(请求未到达网络)抓包显示没有请求。事件查看器不显示任何内容。是否进行了以下注册表更改,尽管这可能只会延迟问题而不是消除它,但无论如何它没有帮助:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lanmanserver\parameters 中找到 autodisconnect 值。如果不存在,请创建一个名为 autodisconnect 的新 REG_DWORD。将值编辑为十六进制并将其设置为 ffffffff.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lanmanworkstation\parameters 中找到 KeepConn。如果它不存在,请将其创建为 REG_DWORD 值并为其分配值 65534.

找到 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters 并创建一个名为 MaxUserPort 的新 DWORD 值。将值设置为 65534。

最终这是由于 Microsoft OS 错误。由于机器是离线机器,它不会自动获得定期更新。安装所有 OS 更新解决了问题。