一:摘要概述
TCP是可靠的传输层协议,网络层采用不靠谱的IP协议导致其自身必须保证数据传输的可靠。其中最终要的就是将丢失的数据包进行重传,当数据包发送后TCP就会开启计时器,当计时器达到阈值且发送的数据包未被数据接收方确认就会重新传递丢失的数据包。当然,重传的前提就是需要确认机制。本文将详细介绍重传与确认,也会涉及到快速重传与延迟确认的概念
二:超时重传模拟
如下编辑一段packetdrill脚本,将ACK响应部分注释,当数据发送方无法获取响应时就会进行数据重传。然后使用tcpdump抓包保存文件,Wireshark进行抓包分析。脚本中就是简单经典的三次握手环节模拟以及数据传输
// 三次握手
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0
+0 < S 0:0(0) win 4000 <mss 1000>
+0 > S. 0:0(0) ack 1 <...>
+.1 < . 1:1(0) ack 1 win 4000
+0 accept(3, ..., ...) = 4
// 数据发送
+0 write(4, ..., 1000) = 1000
// 注释掉数据接收方ACK响应
// +.1 < . 1:1(0) ack 1001 win 1000
+0 `sleep 1000000`
// 抓包命令
tcpdump -i any -nn -vv -w /home/retry.pacp port 8080
三:超时重传分析
首先关心的就是超时重传次数,这个次数由参数/pro/sys/net/ipv4/tcp_retries2
控制,一般默认数值为15。使用命令查看:
[root@zsl home]# cat /proc/sys/net/ipv4/tcp_retries2
15
其次关系的应该就是重传时间,TCP超时重传使用指数避让策略,可以看Wireshark分析图中的红框部分。3-6-12-24......
还有一点必须要纠正,重传的次数并不会由tcp_retries2
完全控制,底层函数实现仅仅只是将其作为参数参考,还会随着RTO
波动动态调整
四:快速重传模拟
与超时重传一致编写packetdrill脚本,tcpdump转包,Wireshark分析