首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >TCP:两个不同的套接字可以共享一个端口吗?

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

Stack Overflow用户
提问于 2012-06-21 06:39:39
回答 6查看 154K关注 0票数 171

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

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

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-06-21 07:32:24

服务器套接字侦听单个端口。该服务器上建立的所有客户端连接都与该连接的服务器端上的同一侦听端口相关联。已建立的连接由客户端和服务器端IP/端口对的组合唯一标识。同一服务器上的多个连接可以共享相同的服务器端IP/端口对,只要它们与不同的客户端IP/端口对相关联,并且服务器将能够处理可用系统资源允许的尽可能多的客户端。

在client-side,上,新的出站连接通常使用随机的客户端端口,在这种情况下,如果您在短时间内建立了大量连接,则可能会耗尽可用端口。

票数 238
EN

Stack Overflow用户

发布于 2014-11-28 13:45:32

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

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

直觉上(也是错误的),大多数人认为它看起来像这样:

代码语言:javascript
运行
复制
    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连接到服务器。既然客户端连接到端口80,那么他的端口也必须是80?这是一件明智的事情,但实际上并不是发生了什么。如果这是正确的,我们只能为每个外部IP地址服务一个用户。一旦远程计算机连接,他就会将端口80连接到端口80,其他人都无法连接。

必须理解三件事:

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

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

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

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

代码语言:javascript
运行
复制
    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上发生了一大堆事情,因为它是一个公共端口,但在功能上没有区别)。

代码语言:javascript
运行
复制
    netstat -atnp | grep -i ":500 "

不出所料,输出为空。现在让我们启动一个web服务器:

代码语言:javascript
运行
复制
    sudo python3 -m http.server 500

现在,以下是再次运行netstat的输出:

代码语言:javascript
运行
复制
    Proto Recv-Q Send-Q Local Address           Foreign Address         State  
    tcp        0      0 0.0.0.0:500             0.0.0.0:*               LISTEN      - 

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

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

代码语言:javascript
运行
复制
    quicknet -m tcp -t localhost:500 -p Test payload.

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

代码语言:javascript
运行
复制
    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,您将看到以下内容:

代码语言:javascript
运行
复制
    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地址之间永远不会有混淆。

票数 258
EN

Stack Overflow用户

发布于 2012-06-21 07:28:20

将连接的套接字分配给新的(专用)端口

这是一种常见的直觉,但它是不正确的。未将连接的套接字分配给新的/专用端口。TCP栈必须满足的唯一实际约束是(local_address、local_port、remote_address、remote_port)的元组对于每个套接字连接必须是唯一的。因此,只要端口上的每个套接字连接到不同的远程位置,服务器就可以具有使用同一本地端口的多个TCP套接字。

请参阅“套接字对”段落:http://books.google.com/books?id=ptSC4LpwGA0C&lpg=PA52&dq=socket%20pair%20tuple&pg=PA52#v=onepage&q=socket%20pair%20tuple&f=false

票数 48
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11129212

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档