TCP的RTO(重传超时时间)计算与指数退避算法
题目描述
TCP通过重传超时时间(Retransmission Timeout, RTO)来判断数据包是否丢失,并触发重传。RTO的计算基于往返时间(Round-Trip Time, RTT)的估计,同时结合指数退避算法避免网络拥塞。面试中常考察RTT的测量方法、RTO的计算公式,以及指数退避的应用场景。
逐步讲解
- RTT的测量与挑战
- 概念:RTT是数据包从发送到接收确认(ACK)的时间间隔。
- 直接测量法:发送方记录每个数据包的发送时间 \(T_{\text{send}}\),收到ACK时记录时间 \(T_{\text{ack}}\),则本次RTT样本为:
\[ \text{RTT}_{\text{sample}} = T_{\text{ack}} - T_{\text{send}} \]
- 问题:若数据包重传后收到ACK,无法区分ACK对应的是原始包还是重传包(即重传二义性),导致RTT样本不准确。
-
解决重传二义性:Karn算法
- 规则1:对重传的数据包,不直接使用其ACK计算RTT样本(避免混淆)。
- 规则2:重传时,RTO采用指数退避(见第4步),直到收到非重传包的ACK后再更新RTT估计。
-
平滑RTT估计:加权平均计算
TCP使用两个变量动态估计RTT:- 平滑RTT(SRTT):对历史RTT样本加权平均,避免瞬时波动。
\[ \text{SRTT} = (1 - \alpha) \times \text{SRTT} + \alpha \times \text{RTT}_{\text{sample}} \]
其中 $\alpha$ 通常取 $1/8$(即SRTT保留7/8历史值,加入1/8新样本)。
- RTT偏差(RTTVAR):衡量RTT变化幅度,用于计算RTO的缓冲。
\[ \text{RTTVAR} = (1 - \beta) \times \text{RTTVAR} + \beta \times |\text{RTT}_{\text{sample}} - \text{SRTT}| \]
其中 $\beta$ 通常取 $1/4$。
- RTO的计算公式
- 基于SRTT和RTTVAR,RTO的计算为:
\[ \text{RTO} = \text{SRTT} + 4 \times \text{RTTVAR} \]
- 初始值:连接建立时,SRTT和RTTVAR未初始化,首个RTO通常设为3秒(Linux默认)。收到首个RTT样本后,按公式更新。
- 下限与上限:RTO通常限制在1秒到60秒之间(避免过长或过短)。
- 指数退避算法
- 触发条件:当数据包超时(RTO到期未收到ACK)时,TCP认为网络可能拥塞。
- 退避规则:重传后,新的RTO按倍数扩大:
\[ \text{RTO}_{\text{new}} = \gamma \times \text{RTO}_{\text{old}} \]
其中 $\gamma$ 通常取2(即**二进制指数退避**)。
- 示例:
- 首次超时:RTO = 1秒 → 重传后新RTO = 2秒
- 第二次超时:RTO = 2秒 → 重传后新RTO = 4秒
- 持续翻倍,直到上限(如60秒)。
- 退出条件:收到非重传包的ACK后,RTO重新基于SRTT和RTTVAR计算。
- 完整流程示例
- 步骤1:发送Seq=1的数据包,记录发送时间。
- 步骤2:收到ACK=2,计算RTT样本,更新SRTT和RTTVAR,得出RTO=200ms。
- 步骤3:发送Seq=2的数据包,超时未收到ACK(RTO=200ms到期)。
- 步骤4:触发重传,RTO退避为400ms(翻倍)。
- 步骤5:若重传成功收到ACK,继续发送新包时,RTO仍保持400ms(Karn算法规则2)。
- 步骤6:后续收到非重传包的ACK后,重新启用标准RTO计算。
总结
TCP通过动态测量RTT、平滑估计SRTT与RTTVAR,并结合指数退避,实现自适应的重传机制。既保证对网络延迟的敏感性,又能在拥塞时降低重传频率,提升网络稳定性。