netstat 的核心价值
netstat 的本质是读取内核网络栈信息。在 Linux 系统中,所有网络连接信息都存储在 /proc 文件系统:
bash
# TCP 连接信息
/proc/net/tcp
/proc/net/tcp6
# UDP 连接信息
/proc/net/udp
/proc/net/udp6
# Unix 域套接字
/proc/net/unix
# 路由表
/proc/net/route
# 网络接口统计
/proc/net/dev
netstat 命令其实就是这些文件的格式化输出工具。了解了这一点,很多输出字段就很好理解了。
常用参数深度解析
1. -tunlp 参数组合
这是最常见的组合,每个字母都有特定含义:
bash
netstat -tunlp
-t: 显示 TCP 连接-u: 显示 UDP 连接-n: 以数字形式显示地址和端口(不做 DNS 解析,快 10 倍以上)-l: 只显示监听状态的套接字-p: 显示进程 ID 和程序名(需要 root 权限)
输出示例:
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1234/nginx
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 5678/mysqld
tcp6 0 0 :::443 :::* LISTEN 1234/nginx
2. -an 参数组合
显示所有连接(包括已建立的):
bash
netstat -an | grep ESTABLISHED
输出字段详解:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 192.168.1.100:22 203.0.113.5:52341 ESTABLISHED
- Recv-Q: 接收队列中等待应用读取的字节数(应该接近 0)
- Send-Q: 发送队列中未收到 ACK 的字节数(高值可能是网络拥塞)
- Local Address: 本地 IP:端口
- Foreign Address: 远程 IP:端口
- State: TCP 连接状态
3. TCP 状态详解
netstat 最强大的功能之一是查看 TCP 状态:
bash
netstat -ant | awk '{print $6}' | sort | uniq -c
输出示例:
12 CLOSE_WAIT
3 ESTABLISHED
45 TIME_WAIT
2 LISTEN
关键状态含义:
| 状态 | 含义 | 排查意义 |
|---|---|---|
LISTEN |
服务端等待连接 | 正常监听状态 |
ESTABLISHED |
连接已建立 | 活跃连接 |
TIME_WAIT |
主动关闭方等待 2MSL | 大量堆积可能导致端口耗尽 |
CLOSE_WAIT |
被动关闭方等待应用关闭 | 大量堆积表示程序 bug |
SYN_SENT |
主动发起连接 | 大量值可能是 SYN Flood 攻击 |
FIN_WAIT1/2 |
关闭握手进行中 | 状态卡住可能是网络问题 |
实战案例:排查连接问题
案例 1:端口占用排查
bash
# 查看端口 8080 的占用情况
netstat -tunlp | grep :8080
# 或者更精确的查找
netstat -tunlp | awk '$4 ~ /:8080$/'
输出:
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 12345/java
案例 2:TIME_WAIT 过多导致端口耗尽
bash
# 统计 TIME_WAIT 数量
netstat -ant | grep TIME_WAIT | wc -l
# 如果超过几千,需要调整内核参数
echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.conf
echo "net.ipv4.tcp_max_tw_buckets = 5000" >> /etc/sysctl.conf
sysctl -p
案例 3:CLOSE_WAIT 堆积问题
CLOSE_WAIT 堆积意味着对方关闭了连接,但本地程序没有调用 close():
bash
# 查看哪些程序产生了 CLOSE_WAIT
netstat -antp | grep CLOSE_WAIT
这通常是程序 bug,需要检查代码中是否正确关闭了 socket。
案例 4:统计并发连接数
bash
# 统计每个 IP 的连接数
netstat -ant | grep ESTABLISHED | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -10
# 输出示例
125 192.168.1.100
45 10.0.0.5
12 203.0.113.10
可以快速发现异常 IP(可能是 DDoS 攻击)。
性能优化:netstat vs ss
netstat 读取 /proc 文件时会遍历所有 socket,在高并发服务器上性能较差:
bash
# 性能对比(10万连接)
time netstat -ant | wc -l # 约 2-3 秒
time ss -ant | wc -l # 约 0.1 秒
ss 命令直接读取内核 netlink socket,速度快 20 倍以上。但 netstat 在低并发场景下足够用,且输出更易读。
高级技巧:持续监控
1. 实时监控连接变化
bash
# 每秒刷新一次
watch -n 1 'netstat -ant | grep ESTABLISHED | wc -l'
2. 监控特定端口
bash
# 监控 80 端口的连接变化
watch -n 1 'netstat -ant | grep ":80 "'
3. 导出网络统计到 CSV
bash
netstat -i | awk 'NR>2 {print $1","$4","$5","$6","$7}' > network_stats.csv
Web 实现:浏览器端的"netstat"
浏览器无法直接访问系统网络栈,但可以通过 WebRTC 获取本地 IP:
typescript
async function getLocalIP(): Promise<string[]> {
return new Promise((resolve) => {
const ips: string[] = []
const pc = new RTCPeerConnection({ iceServers: [] })
pc.createDataChannel('')
pc.createOffer().then(offer => pc.setLocalDescription(offer))
pc.onicecandidate = (event) => {
if (!event?.candidate?.candidate) return
const match = event.candidate.candidate.match(/(\d+\.\d+\.\d+\.\d+)/)
if (match && !ips.includes(match[1])) {
ips.push(match[1])
}
if (pc.connectionState === 'closed') {
resolve(ips)
}
}
setTimeout(() => {
pc.close()
resolve(ips)
}, 1000)
})
}
// 使用
const localIPs = await getLocalIP()
console.log('Local IPs:', localIPs) // ['192.168.1.100', '10.0.0.5']
虽然功能有限,但展示了如何在前端获取网络信息。
常见陷阱
1. DNS 解析拖慢速度
bash
# 慢:会做 DNS 反向解析
netstat -a
# 快:数字形式显示
netstat -an
2. -p 参数需要 root 权限
bash
# 普通用户运行,PID/Program name 显示为空
netstat -tunlp
# 需要 sudo
sudo netstat -tunlp
3. 容器环境中的网络命名空间
Docker 容器有独立的网络命名空间,宿主机的 netstat 看不到容器内的连接:
bash
# 进入容器的网络命名空间
docker exec <container_id> netstat -tunlp
netstat 在线工具
如果你想快速查看网络连接信息,可以试试 Linux netstat 命令查询,提供了命令详解和常用参数说明。
总结
netstat 是网络诊断的基础工具,掌握它可以快速定位大部分网络问题。核心要点:
- 理解
/proc文件系统是数据源 - 掌握
-tunlp和-an参数组合 - 熟悉 TCP 状态及其含义
- 高并发场景用
ss替代 - 结合
watch和管道实现持续监控
下次遇到网络连接问题时,不要只会 ping 和 telnet,试试 netstat,你会看到更多信息。