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 和名称
注意:netstat 在端口多的时候非常慢。我曾在一台生产服务器上跑 netstat -tulnp,等了 8 秒才出结果。那 8 秒里我心里直打鼓——万一这是故障窗口期呢?

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)
我的习惯:现在上服务器第一反应就是 ss -tulnp,而不是 netstat。ss 的输出格式也更干净,脚本解析起来方便。如果你还在用 netstat,我建议你改改习惯——真的快很多。

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)
注意:Windows 的 netstat -b 非常慢,因为它要加载每个 socket 对应的进程模块。我建议先用 netstat -ano 拿到 PID,再去任务管理器里查进程名,这样快得多。

3.2.2 Resource Monitor —— 图形化端口侦探

Windows 自带的资源监视器(Resource Monitor)是个被低估的工具。你可以在「运行」里输入 resmon 打开它,或者从任务管理器的「性能」选项卡进入。

操作步骤:

  1. 打开 Resource Monitor
  2. 切换到「网络」选项卡
  3. 展开「监听端口」区域
  4. 按「端口」列排序,找到目标端口
  5. 看「映像」列——那就是占用进程的名字

Resource Monitor 的好处是实时刷新,而且能直接看到每个端口的网络流量。我曾经用它抓到一个 QUIC 端口冲突:443 端口被一个叫 svchost.exe 的系统进程占了,但那个 svchost 其实是某个第三方 VPN 驱动的宿主进程——这种事用命令行很难一眼看出来。

我的建议:Windows 上做快速排查用 netstat -ano,做深入分析用 Resource Monitor。两个工具互补,一个命令行一个图形化,看场景选。

3.3 端口冲突检测流程图

下面这张图总结了端口冲突的排查路径,我平时就按这个顺序来:

端口冲突检测流程图 端口冲突检测流程图 发现端口冲突 判断操作系统 Linux 环境 Windows 环境 ss -tulnp(推荐) netstat -tulnp(备用) lsof -i :端口(深挖) netstat -ano(快速) netstat -anb(慢但详细) Resource Monitor(图形化) 定位冲突进程 → 解决

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,或者写个循环持续监控。