在 TCP 完成三次握手后,进入数据传输阶段。
与该阶段数据重传的系统参数有(系统默认值):
net.ipv4.tcp_retries1 = 3
net.ipv4.tcp_retries2 = 15
在 /etc/sysctl.conf 中添加或修改,执行sysctl -p 即可生效。
tcp_retries1
数据重传超过阈值tcp_retries1,主要的动作就是更新路由缓存。
查看系统设置
cat /proc/sys/net/ipv4/tcp_retries1
3
测试
略,还不知道怎么测
tcp_retries2
数据重传次数超过 tcp_retries2 会直接放弃重传,关闭 TCP 流。
查看系统设置
cat /proc/sys/net/ipv4/tcp_retries2
15
测试
服务端(192.168.1.24),客户端(192.168.1.21)
启动服务端程序
启动客户端程序
客户端写入数据
服务端断开网络
客户端再次写入数据
./client 192.168.1.24
hello world
hello world
hello?
read: Connection timed out
close sockfd
wireshark 抓包
重传时间拟合
No. timestamp time diff fitting
-1 13.2195
0 13.4253 0.0000 0.0000
1 13.6333 0.2080 0.2000
2 14.0493 0.4160 0.4000
3 14.8813 0.8320 0.8000
4 16.5493 1.6680 1.6000
5 19.8813 3.3320 3.2000
6 26.5532 6.6719 6.4000
7 39.9152 13.3620 12.8000
8 66.6013 26.6861 25.6000
9 119.9133 53.3120 51.2000
10 226.6674 106.7541 102.4000
11 346.9852 120.3178 120.0000
12 467.3078 120.3226 120.0000
13 587.6253 120.3175 120.0000
14 707.9521 120.3268 120.0000
15 828.2653 120.3132 120.0000
如果 RTT 比较小,那么 RTO 初始值就约等于下限 200ms。
No.-1 为数据的正常发送。
No.0 为第一次重传。重传计数器从 0 开始?? 这个地方还有点疑惑
1 < No. <= 10 时间按指数增长。 RTT * 2^No.
No. >10 每次增加 120秒。
优化方案
可以通过减小该数值,减少重试次数,缩短重试时间。
参考文档