问题 .NET / Windows Server中的最大传出套接字连接


我有一个稍微不寻常的情况,我需要在我的服务器上为成千上万的移动用户维护CLIENT tcp连接到另一台服务器(基本上移动设备能够连接到我的中间层服务器,这样可以保持更稳定的连接到移动设备的第三方服务器)。

无论如何,我使用异步套接字(包含在SslStream中)开发了我的服务器应用程序,并且现在有1000个客户端会话全时运行。我对结果感到非常满意,因为我看到单个核心处理器的平均CPU使用率为0-10%,并且随着时间的推移使用了大约60mb的ram。

我的问题是,如何扩展它以便我可以在我的服务器上运行100,000或200,000或更多客户端会话?同样,这有点非传统,因为我的服务器并不像服务器那样,因为我担心传出的连接,而不是传入。

我知道有一个注册表设置MaxUserPort需要更改以超出默认值,似乎是5000.但是,似乎有另一个硬限制65535,我不太清楚该限制所在的位置。 这是每个网络接口的限制吗?它是全局Windows限制吗?这是每个流程的限制吗?

如果它是每个网络接口的限制,我可以添加多个网络接口并将客户端会话套接字绑定到每个接口(例如:接口1上的65k,接口2上的65k等)?

我也不太清楚是什么,如果有任何套接字选项或属性我应该设置来帮助解决问题。现在我没有使用任何套接字选项。

我真的很感激有关这个问题的任何想法,因为很难就这个问题提出明确的建议。谢谢!


4131
2017-11-17 00:38


起源



答案:


Windows机器可以轻松扩展到非常多的打开连接。 64k临时端口限制是每个IP地址,而不是每台机器。如果您需要更多临时端口,请按@SuperTux建议的那样增加限制,但也要为机器分配更多IP。为了利用,您必须在客户端套接字上手动调用Bind()并使用空闲端口从池中传递源IP(这也意味着您将负责跟踪每个地址的可用临时端口计数)。许多高端设备类型设备执行此操作(例如,负载平衡器上的SNAT池)以支持数十万个并发连接。

簿记是一个麻烦,但比为每个64k客户端连接投入未充分利用的硬件更好。


10
2017-11-17 01:51



这是否意味着我可以使用端口0创建本地IPEndPoint,但是具体的网络接口的IP地址,它将确定要使用哪个免费的临时端口?例如:对于120,000个连接,我需要服务器上有2个IP,我负责绑定到每个IP地址的一半连接?我的想法是将进程分配给特定的IP地址,然后将客户端会话帐户分配给IP地址。所以,我想我说'簿记'不会那么糟糕,如果我的假设是正确的,我不必担心哪个特定端口可用于本地绑定 - Redth
另外,我的套接字有什么特别之处吗?是否有我应该使用的特定SetSocketOption(),我是否需要担心UseOnlyOverlappedIO或ExclusiveAddressUse属性? - Redth
正确 - IP堆栈将跟踪各个忙/闲端口。除非您计划在进程之间处理套接字,否则默认套接字选项应该可以正常工作。 - nitzmahone
太好了,谢谢,我不打算在进程或任何东西之间处理套接字。这很简单,我将为每个帐户分配一个IP,并确保分配给IP的帐户不会超过临时端口。 - Redth


答案:


Windows机器可以轻松扩展到非常多的打开连接。 64k临时端口限制是每个IP地址,而不是每台机器。如果您需要更多临时端口,请按@SuperTux建议的那样增加限制,但也要为机器分配更多IP。为了利用,您必须在客户端套接字上手动调用Bind()并使用空闲端口从池中传递源IP(这也意味着您将负责跟踪每个地址的可用临时端口计数)。许多高端设备类型设备执行此操作(例如,负载平衡器上的SNAT池)以支持数十万个并发连接。

簿记是一个麻烦,但比为每个64k客户端连接投入未充分利用的硬件更好。


10
2017-11-17 01:51



这是否意味着我可以使用端口0创建本地IPEndPoint,但是具体的网络接口的IP地址,它将确定要使用哪个免费的临时端口?例如:对于120,000个连接,我需要服务器上有2个IP,我负责绑定到每个IP地址的一半连接?我的想法是将进程分配给特定的IP地址,然后将客户端会话帐户分配给IP地址。所以,我想我说'簿记'不会那么糟糕,如果我的假设是正确的,我不必担心哪个特定端口可用于本地绑定 - Redth
另外,我的套接字有什么特别之处吗?是否有我应该使用的特定SetSocketOption(),我是否需要担心UseOnlyOverlappedIO或ExclusiveAddressUse属性? - Redth
正确 - IP堆栈将跟踪各个忙/闲端口。除非您计划在进程之间处理套接字,否则默认套接字选项应该可以正常工作。 - nitzmahone
太好了,谢谢,我不打算在进程或任何东西之间处理套接字。这很简单,我将为每个帐户分配一个IP,并确保分配给IP的帐户不会超过临时端口。 - Redth


65355是IP协议的限制,更重要的是大多数操作系统的TCP / IP堆栈的限制。

增加最大数量 短暂的港口 在Windows上,请按照下列步骤操作:

  1. 启动注册表编辑器
  2. 在注册表中找到以下子项,然后单击“参数”: HKEY_LOCAL_MACHINE \系统\ CurrentControlSet \服务\ TCPIP \参数
  3. 在“编辑”菜单上,单击“新建”,然后添加以下注册表项:

    价值名称: MaxUserPort的

    值类型: DWORD

    价值数据: 65534

    有效范围: 5000-65534(十进制)

    默认: 0x1388(小数点后5000)

    说明:此参数控制程序从系统请求任何可用用户端口时使用的最大端口号。通常,短暂(短期)端口在1024和5000之间分配。

通常要缩放到 超过65K端口 您将在群集中使用多个服务器。


2
2017-11-17 01:05