如何查看已绑定未监听的Socket端口及所属进程?
这确实是个容易让人困惑的场景——当你调用bind()把socket绑定到端口后还没执行listen(),常规的netstat或lsof默认输出可能找不到这个端口的信息。下面给你两种方向的解决方案:
一、直接查看所有已绑定端口(含未监听的)
1. 使用ss命令(推荐,比netstat更全面)
ss是Linux下替代netstat的工具,默认会包含所有状态的socket,包括那些只绑定但未监听的。针对你的TCP端口5001,执行:
ss -t -a -p | grep 5001
参数说明:
-t:只显示TCP socket-a:显示所有状态(包括未监听、未连接的)-p:显示对应的进程信息
如果你的socket确实绑定成功,这里会输出对应的进程名和PID。
2. 调整lsof的参数
默认情况下,lsof只显示处于LISTEN或ESTABLISHED状态的socket。要看到所有状态的TCP socket,需要加上-s TCP:ALL参数:
lsof -i :5001 -nP -s TCP:ALL
参数说明:
-nP:禁用域名解析和端口名解析,加快输出-s TCP:ALL:显示所有TCP状态的socket,包括仅绑定的
二、通过Socket描述符查看端口/IP信息
如果你的进程还在运行,可以通过/proc文件系统直接查看进程的socket细节:
步骤1:找到进程PID
用ps命令定位你的进程:
ps aux | grep <你的进程名称>
步骤2:查看进程的TCP socket信息
进入进程的/proc目录,查看net/tcp文件(TCP socket的详细记录):
cat /proc/<PID>/net/tcp
这个文件的每一行代表一个TCP socket,重点看这几列:
- 第2列:本地地址,格式为
IP:PORT,其中端口是十六进制(比如5001的十六进制是1389,所以会显示为00000000:1389,表示绑定到所有IP的5001端口) - 第7列:socket的inode号
步骤3:关联到socket描述符
查看进程的文件描述符目录,找到对应inode的socket:
ls -l /proc/<PID>/fd
输出中会有类似lrwx------ 1 user user 64 Aug 10 12:34 3 -> socket:[123456]的行,其中123456就是inode号,和/proc/<PID>/net/tcp里的第7列对应,这个3就是该socket的描述符。
步骤4:验证描述符对应的端口
也可以用ss通过inode查询:
ss -t -a -i | grep <inode号>
就能看到这个socket的端口、状态等信息。
补充:为啥常规命令看不到?
netstat默认只显示处于LISTEN、ESTABLISHED、TIME-WAIT等常见状态的socket,而仅执行bind()的TCP socket处于IDLE(或UNCONN)状态,不在默认过滤范围内。ss和调整参数后的lsof则会包含这些状态的socket。
内容的提问来源于stack exchange,提问作者javierdvalle

