far*_*oft 7 linux networking centos webserver
有多少进程可以侦听特定端口(例如 80 )?以及某些应用程序的子进程如何使用相同的端口进行侦听?侦听端口或建立侦听连接之间有什么区别吗?
Q: How many processes can listen on a specific port?
A: as many as you can spawn.
However for SOCK_STREAM sockets at least, and unless you use the SO_REUSEPORT option (new in Linux 3.9), a process cannot bind a socket to a local endpoint (address+port for TCP, filename for Unix...) if there's already another socket bound on that (or a listening one on that port with the wildcard address).
So unless you use SO_REUSEPORT, the only way to have different processes listen on the same port is to have their corresponding file descriptors pointing to the same open file description (to the same socket).
That happens automatically when you fork() a process. If fd 3 points to a listening TCP socket on the wildcard address and port 12345, both processes after the fork will be listening on that port on that fd (zsh syntax below):
$ 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)
Run Code Online (Sandbox Code Playgroud)
For processes that are not related, the only way (that I know) for a process to get access to that listening socket would be to use the SCM_RIGHT mechanism to pass fds (actually more like open file descriptions) between processes using unix domain sockets.
You'll notice that one argument to listen() is the backlog.
As soon as there's a socket listening on given endpoint, the kernel will start accepting incoming connections to that endpoint (the backlog is a hint to the kernel as to how many it may accept that have not been accepted by applications).
然后,accept()在任何指向侦听套接字(或任何带有 的侦听套接字SO_REUSEPORT)的 fd 上执行 an 的第一个进程将获得传入连接。accept()创建一个新的套接字,并返回一个新的 fd socket。反过来,该 fd 可以被复制(一个新的 fd 指向同一个套接字)并且子进程将继承该连接的套接字,就像他们正在监听的套接字一样。
此答案讨论 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
Run Code Online (Sandbox Code Playgroud)
需要唯一的是 4 元组(remote-ip, remote-port, local-ip, local-port)。由于(remote-ip, remote-port)处于 LISTENING 状态的 是*:*,因此只有一个进程可以监听。
监听应用程序将在每个传入连接上启动一个新的线程/任务/进程。