在单个 IP 上保持超过 65535 个连接
Posted
技术标签:
【中文标题】在单个 IP 上保持超过 65535 个连接【英文标题】:Maintaning more than 65535 connections on single IP 【发布时间】:2016-07-10 10:21:10 【问题描述】:阅读以下文章:10M concurrent websockets
因此,有 1000 个 websocket 服务器在端口 10000-11000 上侦听。当与这些服务器之一建立连接时,我假设它们继续从随机建立的 TCP 连接与随机端口进行通信。那么,一个IP,有64K端口,怎么能保持10M的连接呢?连接是否由 IP 端口对标识?是否可以建立从不同 IP 到同一端口的两个不同连接?这在引擎盖下是如何工作的?
【问题讨论】:
【参考方案1】:当与这些服务器之一建立连接时,我假设它们会继续从随机建立的 TCP 连接与随机端口进行通信。
错误的假设。它们使用正在侦听的相同本地端口号与客户端通信。
那么,一个IP,有64K端口,怎么能维持10M的连接呢?
没问题。
连接是否由 IP 端口对标识?
是的。
是否可以建立从不同 IP 到同一端口的两个不同连接?
是的。
这在后台是如何工作的?
见上文。 IP:端口对。您回答了自己的问题。
【讨论】:
【参考方案2】:很抱歉完全改变了我的答案。
如果机器有足够的内存和处理能力,Linux 可以轻松支持数百万个打开的套接字。 TCP/IP 堆栈允许这样做,因为给定 TCP 数据包的 OS 目标套接字由源和目标 IP 和端口元组确定。
实现 websocket 协议的服务器只需要监听单个 TCP 套接字,通常由 HTTP 或 HTTPS 端口号定义,但在此示例中没有。作为标准 TCP 握手的一部分,服务器操作系统和应用程序在收到 HTTP 请求(即 websocket 请求)时打开一个唯一的套接字,用于与新客户端的 TCP 连接。 websocket 包负责将这个新套接字上使用的协议从标准 HTTP 升级到 websocket。
在示例中,为每个 websocket 套接字启动一个 goroutine。
客户端,即发起 TCP 连接的一方,受到其操作系统可以为给定目标主机和端口打开的临时端口数量的限制。老实说,我不知道这是客户端操作系统的限制还是 TCP/IP 规范本身的限制。
【讨论】:
如果都在一个套接字上,为什么服务器和客户端需要所有这些 FD,以及大量积压,以及增加端口号的所有内容? 我的第一个答案是错误的。但是需要增加端口号只是因为测试使用单个操作系统来运行客户端。【参考方案3】:我认为您缺少的部分是 TCP 连接实际上是两对 IP:PORT。
一个用于服务器,一个用于客户端。
tcp 套接字的侦听端通常总是相同的 IP/端口对。
示例:net.Listen("tcp", ":8080")
正在侦听端口 8080(在本例中为所有接口)
连接(客户端)端通常使用单个传出 IP 和随机端口。
示例:net.Dial("tcp","server:8080)
选择一个随机可用的临时端口,然后尝试连接到 server:8080
。
因此,在上面的示例中,该连接是:client.ip:32768 -> server.ip:8080
(其中 32768 是选择的临时端口)
这两对组合在一起形成了独特的联系。
服务器端可以从单个客户端获取与可用(客户端)端口一样多的连接。只要有 IP 地址,它也可以占用尽可能多的客户端。
可以把它想象成,对于一个监听套接字,理论上你可以有 2^16(ports) * 2^32(ipv4 addrs) 连接。
实际上,有保留的 IP、端口、内存限制等,所以数量要小得多。
例如,Linux 上的临时端口范围是 32768 - 61000。这意味着如果我 net.Dial("tcp", "server:8080")
超过 28232 次,我将开始收到错误,因为我将用尽给定服务器地址的临时端口范围。但是如果服务器监听 2 个独立的端口,我可以对第一个端口执行 28232,对第二个端口执行另一个 28232。
当您看到人们进行 10MM 连接测试时,他们必须使用多个客户端 IP 或多个服务器 IP/端口来实现这一点(或两者的组合以获得 10MM 唯一客户端:IP/服务器:IP 对)
【讨论】:
以上是关于在单个 IP 上保持超过 65535 个连接的主要内容,如果未能解决你的问题,请参考以下文章
解决Android单个dex文件不能超过65535个方法问题