用 tcpdump 分析 TCP 问题
抓包是判断「问题到底出在哪一段」的终极手段:先用过滤表达式锁定目标流,再按重传、重复确认、零窗口、RST 这几类特征逐项核对。现场抓包要选对位置——宿主机网卡、容器内接口、负载均衡两侧看到的报文并不相同,选错网卡会得出完全相反的结论。
基本信息
| 适用平台 | Linux/macOS(tcpdump)、Windows(WinDump/自带 pktmon) |
|---|---|
| 常用选项 | -nn 不解析域名与端口名、-i 指定网卡、-w 存盘、-c 限制包数 |
| 过滤语法 | BPF:host/port/and/or/not、tcp[tcpflags] 按标志位过滤 |
| 深入分析 | 存成 pcap 交给 Wireshark 看时序与统计 |
| 权限 | 需要 root 或 CAP_NET_RAW |
| 注意 | 生产抓包要限包数与大小,避免磁盘被写满 |
典型使用场景
- 排查连接建立失败:看 SYN 是否发出、有无 SYN-ACK、是否有 RST 回击
- 分析重传与乱序,判断丢包发生在哪一段
- 确认零窗口:接收方应用读取慢导致的吞吐停滞
- 核对 TLS 握手:看 ClientHello 的 SNI 与 ALPN 是否符合预期
- 留存证据:把关键时段存成 pcap,便于事后复盘与工单举证
常用过滤与用法
常用过滤与用法
tcpdump -nn -i any 'tcp port 8080 and host 10.0.0.9' -c 100 # 锁定目标流
# 只看握手:抓 SYN 或 SYN-ACK
tcpdump -nn 'tcp[tcpflags] & (tcp-syn|tcp-ack) != 0' -c 20
# 只看被重置的连接
tcpdump -nn 'tcp[tcpflags] & tcp-rst != 0' -c 10
# 存盘后用 Wireshark 做时序与吞吐分析
tcpdump -nn -s 0 -w trace.pcap 'host 10.0.0.9 and port 8080'
# 抓包期间统计各类包数量
ss -s症状对照
| 症状 | 抓包表现 | 含义 |
|---|---|---|
| 重传 | 同一序号多次发送 | 数据或 ACK 在路径上丢失 |
| 重复 ACK | 相同的确认号连续出现 | 对端在催促缺失的那一段 |
| 零窗口 | 窗口字段为 0 | 接收方应用不读数据,缓冲已满 |
| 大量 RST | 标志位 R | 连接被拒绝或被中间设备重置 |
| 只在三次握手失败 | SYN 重传无应答 | 目标未监听、被防火墙丢弃或回程路由有问题 |
| 数据正常但连接偶发中断 | FIN 后无 ACK | 对端异常重启或设备超时清理会话 |
Wireshark 打开 pcap 后,用 Statistics → TCP Stream Graphs 看吞吐与窗口随时间的变化最直观;Expert Information 面板会直接汇总重传、零窗口、RST 等异常计数,比逐包翻找效率高得多。
抓包文件可能包含明文凭据、会话 Cookie 与业务数据,属于敏感资料:只保存在受控目录、按需脱敏,排查完成后及时删除,不要随手发到聊天工具或工单系统里。