有多少进程可以侦听特定端口(例如 80)?某些应用程序的子进程如何使用同一端口进行侦听?侦听端口或建立侦听连接有什么区别吗?
答案1
问:一个特定端口可以监听多少个进程?
答:能生成多少就生成多少。
SOCK_STREAM
然而,至少对于套接字来说,除非您使用该SO_REUSEPORT
选项(Linux 3.9 中的新选项),否则如果已经绑定了另一个套接字,则进程无法将套接字绑定到本地端点(TCP 的地址+端口,Unix 的文件名...)那个(或该端口上带有通配符地址的侦听端口)。
因此,除非使用 SO_REUSEPORT,否则让不同进程监听同一端口的唯一方法是让它们相应的文件描述符指向同一个端口。打开文件描述(到同一个插座)。
当你fork()
创建一个进程时,这会自动发生。如果 fd 3 指向通配符地址和端口 12345 上的侦听 TCP 套接字,则 fork 之后的两个进程都将侦听该 fd 上的该端口(zsh
语法如下):
$ zmodload zsh/net/tcp
$ ztcp -ld 3 12345
$ sleep 10 &
$ lsof -ni tcp:12345
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
zsh 26277 stephane 3u IPv4 506354 0t0 TCP *:12345 (LISTEN)
sleep 26988 stephane 3u IPv4 506354 0t0 TCP *:12345 (LISTEN)
对于不相关的进程,进程访问该侦听套接字的唯一方法(据我所知)是使用SCM_RIGHT
机制传递fds(实际上更像是打开文件描述)在使用 unix 域套接字的进程之间。
你会注意到,一个参数listen()
是积压。
一旦有套接字在给定端点上侦听,内核将开始接受到该端点的传入连接(积压是向内核暗示它可以接受多少尚未被accept
应用程序编辑的内容)。
accept()
然后,第一个对任何指向侦听套接字(或任何具有 的侦听套接字)的 fd进行操作的进程SO_REUSEPORT
将获得传入连接。accept()
创建一个新的套接字,并向该套接字返回一个新的 fd socket
。反过来,该 fd 可以被复制(一个新的 fd 指向同一个套接字),并且子进程将继承该 fd连接的就像他们对监听者一样。
答案2
此答案讨论 IPv4 上的 TCP。
只有一个进程可以听用于新的连接。如果多个进程尝试声明同一端口,您将收到“地址已使用”错误。
这与主动使用该端口的进程数量完全不同。
看一下以下输出:
remote local state
*:* - 4.3.2.1:5000 LISTENING
1.2.3.4:12345 - 4.3.2.1:5000 CONNECTED
4.5.6.7:83247 - 4.3.2.1:5000 CONNECTED
需要唯一的是 4 元组(remote-ip, remote-port, local-ip, local-port)
。由于(remote-ip, remote-port)
处于 LISTENING 状态的 是*:*
,因此只有一个进程可以监听。
监听应用程序将在每个传入连接上启动一个新的线程/任务/进程。