【问题标题】:Windows limitation on number of simultaneously opened sockets/connections per machineWindows 对每台机器同时打开的套接字/连接数的限制
【发布时间】:2012-03-18 06:10:10
【问题描述】:

假设我有一个带有一个真实网络接口和几个环回接口的 Windows 7。 我有启用 IOCP 的服务器,它接受来自客户端的连接。 我正在尝试尽可能多地模拟与服务器的真实客户端连接。

我的客户端代码只是建立了 X 个套接字连接 (注意客户端绑定到给定的接口):

        const Int32 remotePort = 12345;
        const Int32 MaxSockets = 60000;

        Socket[] s = new Socket[MaxSockets];
        IPEndPoint bindEndpoint = new IPEndPoint(IPAddress.Parse(args[0]), 0);
        for (Int32 i = 0; i < MaxSockets; i++)
        {
            s[i] = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            s[i].SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            s[i].Bind(bindEndpoint);
            s[i].Connect(args[1], remotePort);

            IPEndPoint socketInfo = (IPEndPoint)s[i].LocalEndPoint;
            Console.WriteLine(String.Format("Connected socket {0} {1} : {2}", i, socketInfo.Address, socketInfo.Port));
        }

在环回接口上,我有几个用于绑定的 IP。 另外,我也用真实的接口来绑定。 当每台机器打开的套接字数量约为 64K 时,我遇到了问题:

未处理的异常:System.Net.Sockets.SocketException:无法对套接字执行操作,因为系统缺少足够的缓冲区空间或队列已满

我尝试了几种无助的方法,例如: - 在注册表中将 MaxUserPort 设置为最大值和一些其他推荐的 TCPIP 设置。 - 尝试在不同的接口(真实接口和环回)上运行两个服务器并使用多个客户端。

这是 Windows 中已知的限制还是有可能以某种方式克服它?

感谢您的帮助!

【问题讨论】:

  • 查看answer
  • 谢谢,我已经阅读了那个帖子,但它并没有真正回答这个问题。我已经尝试过 CharlesO 的做法,但并没有真正奏效。
  • “注意客户端绑定到给定的接口”。为什么?
  • 通常是因为 TCP/IP 限制每个 IP 地址的端口数。所以,我想要,例如在 interface1 上开放 64K 端口,在 interface2 上开放 64K 端口,依此类推。但是我可以在系统中所有接口上绑定的端口总数/总量仍然在 64K 左右。例如。这是帖子:stackoverflow.com/a/634547/1238124

标签: windows sockets networking iocp


【解决方案1】:

我开发了一个负载测试工具。

在 Windows 10/16G RAM 上运行,可以成功与服务器建立 60,000 个连接。

但是当尝试创建更多连接时,该工具很快会报告“socket WinError 10055 No Buffer Space Available”。

根据this article,我认为限制是整个操作系统的整体套接字缓冲区大小,而不是打开的文件数。

【讨论】:

    【解决方案2】:

    TCP 和 UDP 都使用无符号的 16 位整数来指定端口号。我不认为任何操作系统中的任何实现最多能够为每个绑定地址打开超过 65535 个套接字。此外,如果 Windows 没有为每个适配器或每个绑定地址实现完全隔离的状态表,而是依赖于全局状态表,我也不会感到惊讶。如果是这种情况,这将是一个 Windows 网络架构限制,而不是一个可配置的软限制。

    【讨论】:

      【解决方案3】:

      我在一些 Microsoft 页面上发现:

      ... HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\MaxUserPort 注册表子项被定义为最大端口,最多可以为通配符绑定分配端口。 MaxUserPort 注册表项的值定义了动态端口范围...

      所以,如果我强制端点使用某个端口,例如

      IPEndPoint bindEndpoint = new IPEndPoint(IPAddress.Parse(args[0]), 54321);
      

      然后我可以在系统中同时打开超过 64K 个套接字。

      【讨论】:

        【解决方案4】:

        在您的代码示例中,您正在调用Bind(bindEndpoint),但您没有显示bindEndpoint 的定义方式。检查:

        • 您的系统实际上有多个 IP 地址(环回不计算在内)
        • 您实际上是在将端点的 IP 地址设置为 IP 地址(不是环回)
        • 绑定分布在多个 IP 地址中

        环回地址不计算在内,因为许多系统将其专门用于路由和绑定目的。因此,绑定到环回中的端口可能会占用所有地址的端口,就像绑定到 INADDR_ANY (0.0.0.0) 一样。

        【讨论】:

        • 我现在已经放了完整的代码。正如我所解释的,即使我在不​​同的接口(真实和环回,或仅环回)上绑定:interface1 上的 server1 和 client1,interface2 上的 server2 和 client2 等,每个系统打开的最大套接字数仍约为 64K。跨度>
        猜你喜欢
        • 1970-01-01
        • 2011-05-22
        • 2016-05-01
        • 1970-01-01
        • 2021-10-22
        • 1970-01-01
        • 2023-03-21
        • 1970-01-01
        相关资源
        最近更新 更多