gpt4 book ai didi

sockets - TCP:两个不同的套接字可以共享一个端口吗?

转载 作者:可可西里 更新时间:2023-11-01 02:43:25 25 4
gpt4 key购买 nike

这可能是一个非常基本的问题,但它让我感到困惑。

两个不同连接的套接字可以共享一个端口吗?我正在编写一个应用程序服务器,它应该能够处理超过 100k 的并发连接,并且我们知道系统上可用的端口数约为 60k(16 位)。连接的套接字被分配给一个新的(专用)端口,因此这意味着并发连接数受端口数的限制,除非多个套接字可以共享同一个端口。所以问题。

最佳答案

TCP/HTTP监听端口:多个用户如何共享同一个端口

那么,当服务器监听 TCP 端口上的传入连接时会发生什么?例如,假设您在端口 80 上有一个 Web 服务器。假设您的计算机的公共(public) IP 地址为 24.14.181.229,而尝试连接到您的人的 IP 地址为 10.1.2.3。此人可以通过打开到 24.14.181.229:80 的 TCP 套接字来连接到您。很简单。

凭直觉(但错误地),大多数人认为它看起来像这样:

    Local Computer    | Remote Computer
--------------------------------
<local_ip>:80 | <foreign_ip>:80

^^ not actually what happens, but this is the conceptual model a lot of people have in mind.

这很直观,因为从客户端的角度来看,他有一个 IP 地址,并连接到 IP:PORT 的服务器。既然client连接的是80端口,那他的端口也一定是80吧?这是一个明智的想法,但实际上并非如此。如果这是正确的,我们只能为每个外国 IP 地址的一个用户提供服务。一旦远程计算机连接,他就会占用端口 80 到端口 80 的连接,其他人无法连​​接。

必须了解三件事:

1.) 在服务器上,进程正在监听 端口。一旦获得连接,它就会将其交给另一个线程。通信从不占用监听端口。

2.) 操作系统通过以下 5 元组唯一标识连接:(本地 IP、本地端口、远程 IP、远程端口、协议(protocol))。如果元组中的任何元素不同,那么这是一个完全独立的连接。

3.) 当客户端连接到服务器时,它会选择一个随机的、未使用的高阶源端口。这样,单个客户端最多可以为同一目标端口与服务器建立约 64k 个连接。

所以,这就是客户端连接到服务器时创建的内容:

    Local Computer   | Remote Computer           | Role
-----------------------------------------------------------
0.0.0.0:80 | <none> | LISTENING
127.0.0.1:80 | 10.1.2.3:<random_port> | ESTABLISHED

看看实际发生了什么

首先,让我们使用 netstat 查看这台计算机上发生了什么。我们将使用端口 500 而不是 80(因为端口 80 上发生了一大堆事情,因为它是一个公共(public)端口,但在功能上它没有什么区别)。

    netstat -atnp | grep -i ":500 "

正如预期的那样,输出为空白。现在让我们启动一个网络服务器:

    sudo python3 -m http.server 500

现在,这里是再次运行 netstat 的输出:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State  
tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN -

所以现在有一个进程在端口500上主动监听(状态:LISTEN)。本地地址是0.0.0.0,这是“监听所有ip地址”的代码。一个容易犯的错误是只监听端口 127.0.0.1,它只接受来自当前计算机的连接。所以这不是一个连接,这只是意味着一个进程请求 bind() 到端口 IP,并且该进程负责处理到该端口的所有连接。这暗示了每台计算机只能有一个进程监听端口的限制(有多种方法可以使用多路复用来解决这个问题,但这是一个复杂得多的主题)。如果网络服务器正在监听端口 80,则它不能与其他网络服务器共享该端口。

现在,让我们将用户连接到我们的机器:

    quicknet -m tcp -t localhost:500 -p Test payload.

这是一个简单的脚本 ( https://github.com/grokit/quickweb ),它打开一个 TCP 套接字,发送有效负载(在本例中为“测试有效负载。”),等待几秒钟并断开连接。发生这种情况时再次执行 netstat 会显示以下内容:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State  
tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN -
tcp 0 0 192.168.1.10:500 192.168.1.13:54240 ESTABLISHED -

如果您连接到另一个客户端并再次执行 netstat,您将看到以下内容:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State  
tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN -
tcp 0 0 192.168.1.10:500 192.168.1.13:26813 ESTABLISHED -

...也就是说,客户端使用了另一个随机端口进行连接。因此 IP 地址之间永远不会混淆。

关于sockets - TCP:两个不同的套接字可以共享一个端口吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39708112/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com