ss -lnp
在服务器中显示以下信息:
# ss -lnp
Recv-Q Send-Q Local Address:Port Peer Address:Port
0 128 :::22 :::* users:(("sshd",3847,4))
0 128 *:22 *:* users:(("sshd",3847,3))
0 10 127.0.0.1:25 *:* users:(("sendmail",1605,4))
0 128 127.0.0.1:199 *:* users:(("snmpd",22765,8))
0 128 :::80 :::* users:(("httpd2-prefork",15058,4),("httpd2-prefork",2235,4),("httpd2-prefork",1209,4))
#
根据输出,ss
人们可能会认为 Apache 仅侦听所有 IPv6 地址上的 TCP 端口 80。实际上 Apache 也通过 IPv4 处理请求。为什么会这样?另外,PID 15058、2235 和 1209 怎么可能都监听同一个 TCP 端口?
答案1
1) 如果您监听 ipv6 端口上的连接,Linux 的工作方式如下(默认)。
- https://utcc.utoronto.ca/~cks/space/blog/linux/Ipv6DualBinding
- https://utcc.utoronto.ca/~cks/space/blog/programming/ModernIPv6Handling
2) 进程共享相同的“套接字”,该“套接字”已创建并“绑定”到端口 80。
在这种情况下,它是共享的,因为进程在打开套接字后分叉(克隆)。这与继承打开文件的分叉进程完全相同。就像您运行时一样ls
,它从 shell 继承文件描述符,其中包括一个允许它将输出写入终端的句柄。 Unix 将很多东西视为文件:)。
但是,不可能绑定第二个套接字来侦听同一端口(无论您是什么进程)。 (迂腐:除非两个进程都使用SO_REUSEPORT)。