网络调试与流量控制
七月 18, 2025 [network] #tcp #debug #tc #wireshark #troubleshooting网络调试与流量控制
TCP 异常关闭场景分析
关键概念
- RST(Reset):异常终止连接,接收方得到
Connection reset by peer - FIN:正常关闭连接,接收方 Recv 返回 0
- Broken Pipe:向已收到 RST 的连接写入数据
TIME_WAIT
主动关闭方进入 TIME_WAIT(2MSL,约 60 秒)的原因:
- 确保最后的 ACK 能重传给被动关闭方
- 防止旧连接的残余数据包干扰同五元组的新连接
异常场景总结
| 场景 | 服务器端表现 |
|---|---|
| 客户端 crash(不关 socket 直接退出) | Connection reset by peer(104) |
| 客户端死机/断网/网线松动 | 无任何错误,等超时断开 |
| 客户端正常关闭 Socket | 收完数据后 Recv 返回 0 |
| 服务器已 close,客户端再发包 | 第 1 包发送成功,第 2 包 Broken pipe(32) |
| 服务器接收缓冲区有未读数据时 close | 发送 RST 而非 FIN,客户端收到 104 错误 |
| 服务器先发数据后 close,客户端再发再收 | Windows 端 Recv 报 10053;Linux 端正常收完 |
Broken Pipe 根因
收到 RST 后仍向该连接写数据 → SIGPIPE 信号 + EPIPE 错误。
生产经验
跨服跳转的掉线问题常因服务器在接收缓冲区还有未收数据时关闭 Socket,导致对端收到 RST 而非正常关闭。建议连接关闭由客户端发起。
错误码对照
| Linux | Windows | 含义 |
|---|---|---|
| 104 (ECONNRESET) | 10054 | Connection reset by peer |
| 32 (EPIPE) | 10053 | Broken pipe / connection aborted |
| Recv 返回 0 | Recv 返回 0 | 对端正常关闭 |
局域网 IP 冲突排查
第一步:确认冲突
# arping 检测重复 IP(最权威)
arping -D -c 5 -I eth0 <目标IP>
# 收到多个不同 MAC 的回复 = 冲突确认
# 抓包观察 MAC 抖动
tcpdump -i eth0 arp and host <目标IP> -e -c 20
# 反复刷新 ARP 观察
for i in $(seq 1 10); do
arp -d <目标IP> 2>/dev/null
ping -c 1 -W 1 <目标IP> > /dev/null 2>&1
arp -n <目标IP> | grep ether
sleep 1
done
第二步:定位冲突设备
- 交换机 MAC 表(最可靠):
- Cisco:
show mac address-table address aa:bb:cc:dd:ee:02 - H3C:
display mac-address aa:bb:cc:dd:ee:02 - 华为:
display mac-address-table address aa:bb:cc:dd:ee:02
- Cisco:
- OUI 厂商查询:
curl -s "https://api.maclookup.app/v2/macs/<mac>" - nmap 探测:绑定静态 ARP 后
nmap -O -sV <IP> - mDNS/NetBIOS:
avahi-resolve -a <IP>或nbtscan <IP> - DHCP 租约:
grep "<mac>" /var/lib/dhcp/dhcpd.leases - SNMP 遍历(大型网络):
snmpwalk -v2c -c public <交换机IP> 1.3.6.1.2.1.17.4.3.1.2
处理措施
- DHCP 冲突 → 预留/排除该 IP
- 静态 IP 配错 → 联系管理员修改
- 流氓设备 → 交换机端口 shutdown / MAC 过滤
- 临时止损 → 交换机 IP-MAC 绑定
Linux TC 流量控制
核心概念
| 概念 | 说明 |
|---|---|
| qdisc(排队规则) | 内核发送数据包的排队策略 |
| class(类) | qdisc 内部分类,可嵌套子类 |
| filter(过滤器) | 将数据包分类到指定 class |
无类别 qdisc
- pfifo/bfifo:先进先出(按包数/按字节)
- pfifo_fast:基于 TOS 的三波段优先级队列
- sfq:随机公平队列,按会话轮询
- tbf:令牌桶过滤器,限速
- red:随机早期探测,适合高带宽
HTB(分层令牌桶)
# 创建根 qdisc
tc qdisc add dev eth0 root handle 1: htb default 2
# 创建分类,保证 98M,最大 100M
tc class add dev eth0 parent 1:1 classid 1:2 htb rate 98mbit ceil 100mbit prio 2
# 添加 SFQ 叶子 qdisc
tc qdisc add dev eth0 parent 1:2 handle 2: sfq perturb 10
# 过滤特定 IP 到指定 class
tc filter add dev eth0 protocol ip parent 1:0 u32 match ip src 192.168.0.2 flowid 1:2
常用命令
tc qdisc del dev eth0 root # 清除所有规则
tc -s -d qdisc show dev eth0 # 查看 qdisc 统计
tc -s -d class show dev eth0 # 查看 class 统计
网卡子接口
ip addr add 2.2.2.2/24 dev eth0 label eth0:0 # 添加 IP 别名
ip addr del 2.2.2.2/24 dev eth0 label eth0:0 # 删除
永久生效需在 /etc/sysconfig/network-scripts/ 下创建配置文件。
链路组播地址 224.0.0.252
LLMNR(Link-Local Multicast Name Resolution):Windows 在 DNS 解析失败后,向 224.0.0.252 发送多播查询,局域网内主机若匹配则单播回复自己的 IP。常用于无 DNS 服务器的小型局域网。
tcpdump -i eth0 'udp port 5355 or host 224.0.0.252' -nn