在 Linux 上测试(特别是:Ubuntu 20.04 LTS,内核 5.4.0):在 Python 中:
from socket import *
s1 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
s1.bind(('', 11001))
s2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
s2.bind(('', 11001)) ## Here it fails: EADDRINUSE
因此,在 s1 绑定时,端口使用已经在系统中的某个位置注册。
但是,除非我在套接字上调用listen()
或connect()
,否则它不会显示在我能找到的任何注册表中。/proc/net/tcp
没有列出它,也
netstat
没有ss
。lsof
列出它但没有端口:
python3 28296 netch 5u sock 0,9 0t0 4311999 protocol: TCP
python3 28296 netch 6u sock 0,9 0t0 4312006 protocol: TCP
仅当我在套接字上调用listen()时,它才会出现在可见列表中:
$ ss -at | grep 11001
LISTEN 0 128 0.0.0.0:11001 0.0.0.0:*
这里的 TCP 不是一个单一的情况(最初我以同样的方式使用 SCTP 面对过它)。
为了进行比较,FreeBSD(测试过 12.3)立即列出套接字(使用 检查sockstat
):
$ sockstat -P tcp -p 11001
USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS
netch python3.8 797 4 tcp4 *:11001 *:*
有没有工具可以列出此类套接字的存在?是否可以在不迭代所有流程的情况下完成?为什么标准工具(如 netstat、ss)忽略这个问题?
答案1
自我回答:有一个可能的工作秘诀这里,虽然极其麻烦。感谢@AB 在评论中指出。
如果找到更好的解决方案我会更新。