在单个IP上维护超过65535个连接

huangapple go评论85阅读模式
英文:

Maintaning more than 65535 connections on single IP

问题

阅读以下文章:10M并发WebSockets

所以,有1000个WebSocket服务器在10000-11000端口上监听。当连接到其中一个服务器时,我假设它们会从一个随机建立的TCP连接和随机端口继续通信。因此,由于使用了一个IP和64K个端口,如何维持1000万个连接呢?连接是通过IP-端口对进行标识吗?可以建立两个不同IP的连接到同一个端口吗?这在底层是如何工作的?

英文:

Reading the following article: 10M concurrent websockets

So, there are 1000 websocket servers listening on ports 10000-11000. When a connection is made to one of these servers, I assume they continue communication from a random established TCP connection with random ports. So, as one IP is used, and there are 64K ports, how can one maintain 10M connections? Are connections identified by IP-Port pairs? Can two different connections from different IPs to same port be established? How does this work under the hood?

答案1

得分: 3

当连接到这些服务器之一时,我假设它们会使用相同的本地端口号与客户端进行通信。

这是错误的假设。它们使用的是监听的本地端口号与客户端进行通信。

所以,由于只使用一个IP地址,而有64K个端口,如何维持10M个连接呢?

这不是问题。

连接是通过IP-Port对进行标识的吗?

是的。

不同IP地址的两个不同连接是否可以建立到相同的端口?

是的。

这在底层是如何工作的?

请参考上面的回答。使用IP:port对进行通信。你自己回答了这个问题。

英文:

> When a connection is made to one of these servers, I assume they continue communication from a random established TCP connection with random ports.

Wrong assumption. They communicate with the clients using the same local port number they are listening on.

> So, as one IP is used, and there are 64K ports, how can one maintain 10M connections?

Not a problem.

> Are connections identified by IP-Port pairs?

Yes.

> Can two different connections from different IPs to same port be established?

Yes.

> How does this work under the hood?

See above. IP:port pairs. You answered your own question.

答案2

得分: 2

很抱歉,我完全改变了我的回答。

如果机器具有足够的内存和处理能力,Linux可以轻松支持数百万个打开的套接字。这是因为TCP/IP协议栈根据源IP、目标IP和端口元组确定操作系统针对给定TCP数据包的套接字。

实现WebSocket协议的服务器只需监听一个TCP套接字,通常由HTTP或HTTPS端口号定义,但在这个例子中不是这样。作为标准TCP握手的一部分,当接收到WebSocket请求的HTTP请求时,服务器操作系统和应用程序会为与新客户端的TCP连接打开一个唯一的套接字。WebSocket包会负责将此新套接字上使用的协议从标准HTTP升级为WebSocket。

在这个例子中,为每个WebSocket套接字启动了一个goroutine。

客户端,即发起TCP连接的一方,受限于其操作系统为给定目标主机和端口打开的临时端口数量。老实说,我不知道这是客户端操作系统的限制还是TCP/IP规范本身的限制。

英文:

Sorry for totally changing my answer.

Linux can easily support millions of open sockets if the machine has enough memory and processing power. The TCP/IP stack allows this because the socket the OS targets for a given TCP packet is determined by the source and destination IP and port tuple.

The server implementing the websocket protocol need only listen to a single TCP socket, often defined by the HTTP or HTTPS port number, but not in this example. As part of standard TCP handshaking, the server OS and application open a unique socket for the TCP connection to the new client when the HTTP request which is a websocket request is received. The websocket package takes care of upgrading the protocol used on this new socket from standard HTTP to websocket.

In the example, a goroutine is started for each websocket socket.

The client side, the side initiating the TCP connections, is limited by the number of ephemeral ports its OS can open for a given destination host and port. Honestly, I don't know if this is a limitation of the client OS or the TCP/IP specification itself.

答案3

得分: 1

我认为你所缺少的部分是TCP连接实际上是两对IP:PORT。

一对是服务器的,一对是客户端的。

TCP套接字的监听端通常是相同的IP/Port对。

例如:net.Listen("tcp", ":8080") 在端口8080上进行监听(在这种情况下是在所有接口上进行监听)。

连接(客户端)端通常使用一个出站IP和一个随机端口。

例如:net.Dial("tcp","server:8080) 选择一个可用的临时端口,然后尝试连接到server:8080

所以,在上面的例子中,该连接是:client.ip:32768 -> server.ip:8080(其中32768是选择的临时端口)。

这两对组合成一个唯一的连接。

服务器端可以从单个客户端接受多个连接,只要有可用的(客户端端)端口。它还可以接受与可用IP地址一样多的客户端。

可以将其视为,对于一个监听套接字,理论上可以有2^16(端口)* 2^32(IPv4地址)个连接。

实际上,由于保留的IP、端口、内存限制等,这个数字要小得多。

例如,Linux上的临时端口范围是32768-61000。这意味着如果我对给定的服务器地址进行超过28232次的net.Dial("tcp", "server:8080")操作,我将开始收到错误,因为我已经耗尽了临时端口范围。但是,如果服务器在两个不同的端口上进行监听,我可以对第一个端口进行28232次操作,然后对第二个端口进行28232次操作。

当你看到人们进行1000万连接测试时,他们必须使用多个客户端IP或多个服务器IP/端口来实现这一点(或者两者的组合来获得1000万个唯一的client:ip/server:ip对)。

英文:

I think the part you are missing is a TCP connection is actually two pairs of IP:PORT.

One for the server, one for the client.

The listening side of a tcp socket is generally always the same IP/Port pair.

Example: net.Listen("tcp", ":8080") is listening on port 8080 (on all interfaces in this case)

The connecting (client) side is usually uses a single outgoing IP along with a random port.

Example: net.Dial("tcp","server:8080) Selects a random available ephemeral port and then attempts to connect to server:8080.

So, in the above example, that connection is: client.ip:32768 -> server.ip:8080 (where 32768 is the ephemeral port selected)

the two pairs combined make a unique connection.

The server side can take as many connections from a single client as there are available (client side) ports. It can also take as many clients are there are IP addresses.

Think of it as, for one listening socket, you can theoretically have 2^16(ports) * 2^32(ipv4 addrs) connections.

In reality, there are reserved IPs, ports, memory limitations, etc so the number is far smaller.

For exmaple, the ephemeral port range on Linux is 32768 - 61000. Which means I'll start getting errors if I net.Dial("tcp", "server:8080") more than 28232 times as I will have exhausted my ephemeral port range for the given server address. But if the server is listening on 2 separate ports, I can do 28232 to the first port, and another 28232 to the second port.

When you see people do the 10MM connection tests, they have to use multiple client IPs or multiple server IPs/Ports to achieve this (or a combo of both to get 10MM unique client:ip/server:ip pairs)

huangapple
  • 本文由 发表于 2016年3月23日 16:15:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/36172875.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定