Network - TCP Retransmission
Created by : Mr Dk.
2021 / 03 / 09 13:39
Nanjing, Jiangsu, China
About
由于下层网络 (IP) 可能出现报文的丢失、重复或失序,TCP 为了提供可靠的数据传输服务,会要求重传已丢失的包。TCP 有两套独立的机制来完成重传:
- 基于时间的重传 (等待确认信息超时后重传)
- 基于确认信息的构成 (确认信息满足一定的条件立刻重传),通常更高效
一般来说,TCP 拥有两个阈值来决定如何重传同一个报文:
- 愿意尝试重传的次数 (间隔时间加倍,二进制指数退避 (binary exponential backoff))
- 放弃当前连接的超时时间
TCP 需要为重传计时器设置一个超时值,指示等待 ACK 的时间。
基于计时器的重传
TCP 发送端要为每一个报文设置重传计时器,设置超时时间 RTO。如果发送端及时接收到了接收方发回的 ACK,那么相应报文的计时器就被取消。如果没有数据丢失,就不会出现计时器超时。RTO 的理论数值应该会随着网络环境而动态变化,但发送端无法预知。如果 RTO 设置得过高,将导致网络利用率 (吞吐率) 下降;如果 RTO 设置得过低,又会导致很多不必要的重传。但是发送方本身并不知道当前网络中应该使用什么样的 RTO 合适。因此,发送方需要对过往发送和接收的报文进行时间统计,得到基于时间变化的 RTT 测量值,然后根据该值来设置 RTO。
TCP 在收到数据后会返回确认信息,在信息中可以携带时间戳来测量传输该信息需要的时间,每个测量的结果被称为 RTT 样本。每个 TCP 连接的 RTT 均独立计算,TCP 需要根据一段时间内的样本来建立一个估计值,然后根据这个 RTT 的估计值来设置 RTO:
- 经典方法:低通滤波 / 指数加权移动平均
- 标准方法:适用于 RTT 变动较大的情况
- ...
在 RTO 时间内,如果没有收到被计时报文的 ACK,就会触发超时重传。TCP 通过降低当前发送速率来对重传进行响应:
- 基于拥塞控制机制,减小发送窗口大小
- 增大 RTO 的退避因子
通常来说,计时器超时并触发重传不是必要的,因为 RTO 通常设置得很大,基于计时器的重传会使网络利用率下降。需要有更加高效的方法检测和修复丢包。
快速重传
基于接收端的反馈信息,决定是否重传。快速重传能够更加及时地修复丢包。当接收端接收到失序报文段时,TCP 需要立刻生成重复的确认信息,立即发送,从而使发送端尽早得知存在失序的报文,并确认了丢失报文的位置。但是发送重复 ACK 可能会出现在两种情况下:
- 报文丢失
- 报文延时到达 (导致暂时失序)
因此 TCP 需要等待一定数目的重复 ACK (dupthresh) 后,才能对数据是否丢失作出决策。在标准化的实现中,这个阈值为 3;Linux 可以根据当前的失序程度动态调节这个值。
快速重传算法概括如下:TCP 发送端在观测到至少 dupthresh 个重复的 ACK 之后,立刻重传可能丢失的分组,而不必等到重传计时器超时。当然同时也可以发送新的数据。伴随快速重传,通常会触发拥塞控制机制,因为丢包通常与网络拥塞有关。
References
TCP/IP 详解 - 卷 1:协议