'ss' 显示同一端口的多个监听 pid

'ss' 显示同一端口的多个监听 pid

我们的生产代码中有使用“netstat”的 sh 脚本。我们使用命令“netstat -lntup”来检索正在侦听某个端口的所有 pid。我用 ss -lntup 替换了该命令。现在,在大多数情况下,两个命令的输出是相同的,但在某些情况下,“ss”会为同一端口返回多个 pid,例如

# ss -lntup | grep http

tcp  LISTEN 0  128  *:80  *:*  users:(("httpd",pid=2355,fd=4),("httpd",pid=1962,fd=4),("httpd",pid=1961,fd=4),("httpd",pid=1960,fd=4),("httpd",pid=1955,fd=4))

tcp  LISTEN 0  128  *:443  *:*  users:(("httpd",pid=2355,fd=6),("httpd",pid=1962,fd=6),("httpd",pid=1961,fd=6),("httpd",pid=1960,fd=6),("httpd",pid=1955,fd=6))

我应该如何解读该列表? pid 是否以某种方式相关?多个进程可以同时监听同一个pid吗?

谢谢

答案1

pid 是否以某种方式相关?

在这种情况下显然是的。它们要么具有共同的父进程,要么其中一个进程是其他进程的父进程。

公共文件句柄(4 表示端口 80,6 表示端口 443)表明父进程在启动子进程之前创建了一个“套接字”。

多个进程可以同时监听同一个端口吗?

不是进程(pid)在端口上监听,而是“套接字”在端口上监听。

套接字是计算机内存中某些与网络相关的对象。

正如 Eduardo Trápani 已经写的那样,如果使用 SO_REUSEPORT,多个套接字可以侦听一个端口。然而,这里的情况(可能)并非如此。我假设只涉及两个套接字(一个在端口 80 上,一个在端口 443 上):

如果一个进程(pid)创建了一个套接字,然后创建了子进程,则该进程及其子进程通常在创建子进程后共享该套接字。

操作系统知道哪个套接字正在侦听哪个端口,但是因为套接字(至少在官方上)在多个 pid 之间共享,所以它无法找出哪个 pid 正在实际侦听。

我假设只有父进程真正使用套接字;但操作系统无法知道这一点。

答案2

pid 是否以某种方式相关?

不必要。但它们必须属于同一个有效用户 ID,以防止端口劫持。

多个进程可以同时监听同一个pid /端口吗?

是的,使用套接字选项 SO_REUSEPORT。这一页(包括 python 示例)解释了它的工作原理以及它与 SO_REUSEADDR (也用于服务器)的关系。

这是页面的摘录:

SO_REUSEPORT

此选项的行为与 SO_REUSEADDR 的概念类似,但此选项允许我们将多个 TCP/UDP 服务器套接字绑定到完全相同的 IP 和相同端口。

但是套接字有 1 个限制,可以共享完全相同的 IP 和相同端口,这不在 SO_REUSEADDR 中。所有共享 IP/端口的套接字应由具有相同有效用户的进程生成。这可以应用于 UDP/TCP 协议,请注意,仅使用 SO_REUSEADDR 即可绑定多个 UDP 服务器套接字,而无需照顾有效用户(由 root open *:80 执行的 processA 和 userA 执行的 processB 可以使用 SO_REUSEADDR open *:80) 。但 SO_REUSEPORT 不允许。仅从这一点来看,我们可以认为 SO_REUSEPORT 受到更多限制。

相关内容