如何用 netstat / ss 查看网络连接和端口状态?
简化版
netstat 和 ss 都是查看本机网络连接和端口监听情况的工具,ss(socket statistics)是 netstat 的现代替代品,更快(尤其连接海量时)。最常用两件事:① 看哪些端口在监听——ss -tlnp / netstat -tlnp;② 看当前有哪些连接、各是什么状态——ss -tanp / netstat -antp。核心是读懂 TCP 连接状态(LISTEN、ESTABLISHED、TIME_WAIT、CLOSE_WAIT 等),比如大量 CLOSE_WAIT 往往是程序没关连接的 bug,大量 TIME_WAIT 多是短连接高并发。
详细版
常用参数(netstat 和 ss 通用记忆):
| 参数 | 含义 |
|---|---|
-t | TCP 连接 |
-u | UDP |
-l | 只看**监听(LISTEN)**的端口 |
-n | 数字显示(不把端口/IP 反解析成名字,更快) |
-p | 显示占用的进程(PID/程序名,常需 root) |
-a | 所有连接(含监听和非监听) |
① 看监听端口(服务起没起、占了哪些端口):
ss -tlnp # TCP + 监听 + 数字 + 进程
netstat -tlnp # 传统写法,等价
② 看所有 TCP 连接及状态:
ss -tanp # TCP + 全部 + 数字 + 进程
netstat -antp
③ 统计各状态连接数(排查连接堆积超实用):
ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn
netstat -ant | awk '{print $6}' | sort | uniq -c | sort -rn
TCP 连接状态速查:
| 状态 | 含义 | 大量出现意味着 |
|---|---|---|
LISTEN | 端口在监听,等连接 | 正常,服务在跑 |
ESTABLISHED | 连接已建立、正在通信 | 正常,活跃连接数 |
TIME_WAIT | 主动关闭方等 2MSL | 短连接高并发(多为正常) |
CLOSE_WAIT | 被动关闭方还没关 | 程序 bug:收到 FIN 却没 close |
SYN_SENT | 已发 SYN,等回应 | 连不上对方(对端/网络问题) |
SYN_RECV | 收到 SYN,半连接 | 大量 = 可能 SYN Flood 攻击 |
完整版教学
一、这俩工具解决什么问题
netstat / ss 回答的是「我这台机器上,网络层面正在发生什么」:
- 哪些端口开着、在等连接(服务起没起)?
- 现在跟谁建立着连接、多少个(连接活跃度)?
- 这些连接都处于什么状态(有没有异常堆积)?
- 某个端口被哪个进程占用了(端口冲突排查)?
它是服务端排障的第一梯队工具——「端口被占用」「连接数爆了」「CLOSE_WAIT 堆积」这些问题全靠它看。ss 是 netstat 的现代替代(netstat 出自老旧的 net-tools,很多新系统默认只装 ss),用法参数几乎一致,ss 在连接量大时快得多(它直接从内核读,不像 netstat 去遍历 /proc)。
二、参数怎么记:拆开就好背
netstat 和 ss 的参数高度一致,拆开记就不会乱:
- 协议:
-t= TCP、-u= UDP。 - 范围:
-l= 只看 LISTEN(监听)、-a= 全部。 - 显示:
-n= 数字化(不反解析,快)、-p= 显示进程。
所以两个黄金组合背下来就够用:
-tlnp:TCP + 监听 + 数字 + 进程 = 「有哪些端口在监听、分别是哪个程序」。-tanp(ss)/-antp(netstat):TCP + 全部 + 数字 + 进程 = 「所有连接、状态、对端、进程」。
提示:一定要加
-n。不加的话,工具会把 IP 反查成域名、把端口号(如 443)翻成服务名(https),又慢又不直观,排障时统一用数字。
三、场景一:端口被谁占了
启动服务报「Address already in use(端口被占用)」时,用它找出是谁占了端口:
ss -tlnp | grep 8080
# LISTEN 0 128 *:8080 *:* users:(("java",pid=12345,fd=100))
users:(("java",pid=12345)) 直接告诉你是 PID 12345 的 java 进程占了 8080。找到后决定是杀掉它还是换端口。-p 需要权限(普通用户可能看不到别人的进程,加 sudo)。
同时留意监听地址:*:8080 或 0.0.0.0:8080 表示监听所有网卡(外部可访问);127.0.0.1:8080 表示只监听本机回环,外部连不上——这常是「本地测好好的、别的机器连不上」的原因。
四、场景二:统计连接状态,发现堆积
排查「连接数异常」时,最有用的是按状态统计连接数:
ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn
# 6523 TIME_WAIT
# 1204 ESTABLISHED
# 340 CLOSE_WAIT ← 注意!
这一条命令能立刻暴露问题:某个状态数量异常多,就指向特定故障。下面两个状态是面试和实战的重中之重。
五、重点:CLOSE_WAIT 堆积——几乎一定是程序 bug
CLOSE_WAIT 大量堆积,通常是代码 bug,这是超高频考点。理解它要回顾四次挥手:
- 对方(客户端)先关闭连接,发来 FIN;
- 本机内核收到 FIN,自动回 ACK,连接进入
CLOSE_WAIT状态——意思是「对方已经要关了,就等我这边应用调用close()」; - 但如果应用程序一直没有调用
close()(忘了关、异常路径没关、连接池 bug),连接就永远卡在 CLOSE_WAIT,不释放。
所以大量 CLOSE_WAIT = 你的程序收到了对方的关闭请求,却没有关闭自己这端的连接。危害是连接和文件描述符(fd)泄漏,最终耗尽 fd 导致服务无法建立新连接。排查方向:检查代码里 socket/连接是否在所有路径(含异常、finally)都正确关闭。
记忆:CLOSE_WAIT 堆在「被动关闭方」,是「等我关我却不关」——查代码有没有 close()。
六、重点:TIME_WAIT 堆积——多数是正常现象
TIME_WAIT 大量出现,通常不是 bug,别一看到就慌。它出现在主动关闭连接的一方:
- 主动关闭方发完最后的 ACK 后,会进入
TIME_WAIT,等待 2MSL(约 1-4 分钟) 才真正释放; - 目的有二:① 确保最后的 ACK 能到达对方(丢了能重传);② 让本次连接的残留旧数据包在网络中消散,不干扰后续复用同一四元组的新连接。
所以高并发短连接(如每次请求都新建又关闭连接的场景)会主动关闭方积累大量 TIME_WAIT,这是协议设计使然,多为正常。只有当 TIME_WAIT 多到耗尽本地端口、影响新建连接时才需优化:用长连接/连接池减少连接创建(治本),或调内核参数 tcp_tw_reuse 复用(治标,谨慎)。
对比记忆:TIME_WAIT 在主动关闭方、正常、和短连接高并发有关;CLOSE_WAIT 在被动关闭方、异常、是没调 close() 的 bug。
七、其他状态的排查价值
- 大量
SYN_RECV(半连接):可能遭遇 SYN Flood 攻击(大量伪造 SYN 占满半连接队列),或后端处理不过来。 - 一直
SYN_SENT:本机发了 SYN 但收不到对方回应——对端服务没起、或被防火墙拦(呼应端口测试里的 timeout)。 ESTABLISHED数量:反映当前活跃连接数,突增可能是流量高峰或连接泄漏。
八、常见误区与追问
| 考点 | 正确口径 |
|---|---|
| netstat | 传统工具,查看连接、监听端口、路由等 |
| ss | 基于 sock_diag,更快更适合大量连接 |
| 常看状态 | LISTEN、ESTABLISHED、TIME_WAIT、CLOSE_WAIT、SYN_RECV |
ss -lntp
ss -ant state established
ss -s
netstat -rn
netstat -antp
ss更像现代 Linux 下的首选连接观察工具;看端口问题先看 LISTEN,看泄漏问题重点看 CLOSE_WAIT。
- 误区:TIME_WAIT 多一定是故障。 主动关闭方会进入 TIME_WAIT,高并发短连接场景常见,要结合端口耗尽和连接模式判断。
- 误区:CLOSE_WAIT 多是内核问题。 通常是应用收到对端关闭后没有及时 close,重点查应用代码或连接池。
- 误区:ESTABLISHED 多就代表流量大。 长连接空闲也会保持 ESTABLISHED,要结合收发队列和业务指标。
- 追问:Recv-Q/Send-Q 怎么看? Recv-Q 堆积可能应用读慢,Send-Q 堆积可能对端慢或网络发送受阻。
- 追问:如何查哪个进程监听端口? 用
ss -lntp或netstat -lntp查看 PID/program。 - 追问:为什么 ss 比 netstat 快? ss 通过内核 sock_diag 接口获取信息,避免解析大量 /proc 文本。
九、加强记忆
netstat/ss 看本机连接与端口,ss 是更快的现代替代。参数拆记:-tTCP -uUDP -l监听 -n数字 -p进程 -a全部;黄金组合 ss -tlnp(看监听端口+进程)、ss -tanp(看所有连接+状态)。会按状态统计(... | uniq -c)发现堆积。两大状态:CLOSE_WAIT 堆积=被动关闭方没调 close() 的 bug(泄漏 fd);TIME_WAIT 堆积=主动关闭方等 2MSL,多为短连接高并发下的正常现象(治本用长连接/连接池)。