3、端口冲突检测工具:netstat、ss、lsof 命令详解,Windows 下的 netstat 和 Resource Monitor
端口冲突这事儿,说白了就是两个进程抢同一个门。你想想看,QUIC 虽然用了 UDP,但端口号就那么 65535 个,冲突起来一点不比 TCP 少。我在项目里见过最离谱的一次,是 Nginx 和某监控 agent 抢 443 端口,结果 QUIC 连接死活建不起来。
嗯,要解决冲突,第一步就是找到谁在占端口。今天我把 Linux 和 Windows 上最趁手的几把「探针」都给你捋一遍。
3.1 Linux 下的三剑客:netstat、ss、lsof
3.1.1 netstat —— 老牌工具,但有点慢
netstat 我用了十几年,说实话现在有点过时了。但它胜在通用,几乎每个 Linux 发行版都自带。我个人习惯用它做快速排查:
# 查看所有 UDP 监听端口
netstat -uln
# 查看所有 TCP/UDP 监听端口,显示进程名
netstat -tulnp
# 只看 UDP 端口,带进程 PID
netstat -unp
参数拆开讲:
- -u:只显示 UDP
- -l:只显示 LISTEN 状态的端口
- -n:以数字形式显示地址和端口,不反解域名
- -p:显示占用端口的进程 PID 和名称
3.1.2 ss —— 现代替代品,快一个数量级
ss 是 iproute2 包里的工具,现在大部分新系统都推荐用它。为什么快?因为它直接从内核的 socket 哈希表读数据,而 netstat 还要遍历 /proc 文件系统。
# 查看所有 UDP 监听端口
ss -uln
# 查看所有 TCP/UDP 监听,带进程信息
ss -tulnp
# 只看 UDP,显示详细 socket 信息
ss -u -a -p
# 过滤特定端口(比如 443)
ss -ulnp sport = :443
参数说明:
- -u:UDP socket
- -l:只显示 LISTEN
- -n:不反解服务名
- -p:显示进程
- -a:所有状态(包括非 LISTEN)
3.1.3 lsof —— 查进程与端口的「终极武器」
lsof 的全称是 List Open Files。在 Linux 里,socket 也是文件。所以 lsof 能告诉你哪个进程打开了哪个端口。
# 查看某个端口被谁占用(最常用)
lsof -i :443
# 查看 UDP 端口
lsof -i udp:443
# 只看 LISTEN 状态的端口
lsof -i tcp:443 -s tcp:LISTEN
# 查看某个进程打开了哪些端口
lsof -i -a -p 1234
输出示例:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 1234 root 7u IPv4 54321 0t0 UDP *:443
这里 FD 列的 7u 表示文件描述符 7,类型是 IPv4 socket。NAME 列显示绑定的地址和端口。
实战场景:有一次 QUIC 服务启动报错「Address already in use」,我直接用 lsof -i :443 一看,发现是之前残留的旧进程没 kill 干净。lsof 能直接显示 PID,kill 掉就解决了。
3.2 Windows 下的两大利器
3.2.1 Windows netstat —— 和 Linux 版同源但不同命
Windows 也自带 netstat,用法大同小异。我刚开始切到 Windows 环境时,差点被它坑了——因为 Windows 版 netstat 默认不显示进程名,得加个 -b 参数。
# 查看所有监听端口
netstat -an
# 查看 UDP 监听端口,显示进程名(需要管理员权限)
netstat -anb
# 只看 UDP
netstat -anb -p UDP
# 显示进程 PID
netstat -ano
参数差异:
- -b:显示可执行程序名(Linux 没有这个参数)
- -o:显示关联的 PID
- -p:指定协议(UDP/TCP)
3.2.2 Resource Monitor —— 图形化端口侦探
Windows 自带的资源监视器(Resource Monitor)是个被低估的工具。你可以在「运行」里输入 resmon 打开它,或者从任务管理器的「性能」选项卡进入。
操作步骤:
- 打开 Resource Monitor
- 切换到「网络」选项卡
- 展开「监听端口」区域
- 按「端口」列排序,找到目标端口
- 看「映像」列——那就是占用进程的名字
Resource Monitor 的好处是实时刷新,而且能直接看到每个端口的网络流量。我曾经用它抓到一个 QUIC 端口冲突:443 端口被一个叫 svchost.exe 的系统进程占了,但那个 svchost 其实是某个第三方 VPN 驱动的宿主进程——这种事用命令行很难一眼看出来。
3.3 端口冲突检测流程图
下面这张图总结了端口冲突的排查路径,我平时就按这个顺序来:
3.4 实战对比:哪个工具最快?
我整理了一张对比表,方便你根据场景选工具:
| 工具 | 平台 | 速度 | 显示进程名 | 过滤能力 | 推荐场景 |
|---|---|---|---|---|---|
| netstat | Linux/Windows | 慢(Linux)/ 中等(Windows) | 需加 -p(Linux)或 -b(Windows) | 弱 | 临时快速查看 |
| ss | Linux | 快 | 需加 -p | 强(支持 sport/dport 过滤) | 日常首选 |
| lsof | Linux | 中等 | 默认显示 | 强(支持 -i :port) | 深挖某个端口 |
| Resource Monitor | Windows | 实时 | 默认显示 | 中等(按端口排序) | 图形化分析 |
我的经验:在 Linux 上排查 QUIC 端口冲突,我 90% 的情况用 ss -ulnp 就够了。剩下 10% 用 lsof -i :端口 来确认进程详情。Windows 上我习惯先 netstat -ano 拿 PID,然后去任务管理器里看进程名——比等 netstat -b 快多了。
3.5 避坑指南
最后分享几个我踩过的坑:
- sudo 权限问题:lsof 和 ss -p 都需要 root 权限才能看到别人的进程。如果你用普通用户跑,可能只看到自己的进程——明明端口被占了,却查不到是谁。我曾经因为这个排查了半小时。
- Windows 防火墙干扰:Resource Monitor 显示端口在监听,但客户端连不上——可能是防火墙没放行。别光盯着端口占用,也要看一眼防火墙规则。
- IPv6 vs IPv4:有些服务只监听 IPv6(:::443),但你的客户端用 IPv4 去连,看起来像端口没开。ss -uln 会显示
*:443还是:::443,注意区分。 - 短时占用:有些进程启动后很快释放端口,你跑 netstat 时刚好错过。这种情况我建议用 ss -u -a 看所有状态的 socket,或者写个循环持续监控。