Page 433 - 《软件学报》2024年第4期
P. 433
李彤 等: 传输控制中的确认机制研究 2011
能不仅是丢包检测, 还要其他功能比如拥塞控制和传输状态监控等. RACK (recent ACK) 于 2021 年正式成为 RFC
标准 (RFC 8985 [38] ). RACK 是一个丢包检测算法, 它依赖的确认机制还是经典 TCP 的基于 SACK 选项的 Delayed
ACK 机制. 虽然两者命名类似, 但是, RACK 和 TACK 本质上是两个完全不同范畴的概念.
然而, 两者之间也具有一定的联系. 如果一个协议使用 TACK 机制, ACK 数量就会急剧下降, 那么这个协议不
太容易实现仅发送端修改的 RACK. 原因是 ACK 报文间隔时间过长, 最新收到的报文时间戳更新缓慢, 无法支撑
RACK 及时在发送端检测丢包. 这也是 TACK 机制推荐使用基于接收端的丢包恢复策略的原因.
4.2.4 IACK 与 FACK
FACK (Forward ACK) [39] , 准确来说并非某一种具体的 ACK 类型, 而是一个丢包检测和拥塞控制的综合方案.
这里主要讨论 FACK 丢包检测算法的部分.
经典 TCP 默认采用 DupACK [25] , 也称为“3 次重复 ACK”检测丢包. 如图 13 所示, 其原理是“事不过三”, 即如
果一个报文其后续的 3 个报文都到了, 这个报文还没有到达, 则这个报文被认为是丢失报文. 如果在 3 次重复
ACK 到达之前, 已经丢失了多个数据报文, DupACK 算法可能导致不必要的延迟.
如图 14 所示, FACK 算法规定当接收方缓存中的不连续队列长度大于 3 时, 表示发生了丢包事件. 换句话说,
DupACK 算法检测丢包事件的决策条件是 (dupacks == 3), 而 FACK 算法检测丢包事件的决策条件是 ( ( 最大序号 –
最小序号 ) > 3 || (dupacks == 3) ). 其中, dupacks 表示重复 ACK 报文的数目, 最大序号表示接收方缓存中已接收到
的报文最大数据序号, 最小序号表示发送方还没有收到确认的数据序号. 显然, 如果丢失的报文恰好只有 1 个, 则
FACK 算法和 DupACK 算法的效果是一样的. 可以认为, FACK 算法是 DupACK 算法的泛化, 用于解决一个窗口
内多个报文丢包的问题.
发送方 接收方
发送方 接收方
报文 2 丢失
报文 2
报文 3 丢失
ACK1 答复序号为 2 报文 3 最小序号为 2
报文 4 ACK1 最大序号为 3
ACK2 答复序号为 2 报文 4
报文 5 报文 5
检测到丢包 ACK3 答复序号为 2 ACK2 最小序号为 2
检测到丢包 最大序号为 5
重传报文 2 重传报文 2
图 13 经典 TCP DupACK 丢包检测 图 14 FACK 丢包检测
网络中的乱序可能是由于丢包造成的, 也有可能是由于多路径负载均衡等策略引起的. 当网络中存在大量由
非丢包原因引起的乱序时, FACK 算法将会导致大量的不必要的重传. TACK 机制通过在接收方通过乱序来检测
丢包事件, 为了应对非丢包原因引起的乱序, 接收方发送 IACK 之前需要等待一段时间, 称为 IACK 延迟, 类似于
RACK 算法 [39] 中定义的乱序窗口 (通常取 RTT/4). 我们将在后面的章节对 IACK 展开讨论.
4.2.5 IACK 与 RACK
前面提到, RACK 是一个丢包检测算法, 而非某一种具体的 ACK 类型.RACK 检测丢包的原理是, 当发送方认
为某个报文缺失的时间足够久后, 该报文被认为是丢失报文. 这与经典 TCP 采用 DupACK 进行丢包检测的方式
具有本质区别.
在尾包丢失和重传报文丢失的情况下, RACK 相比 DupACK 具有显著优势. 以重传报文丢失为例. DupACK
算法基于计数进行丢包检测, 在重传报文丢失后, 由于发送方无法准确区分重传报文与原始报文, 发送方无法明确
地检测到重传报文丢失事件, 因此可能导致开销较大的超时重传. 而 RACK 基于计时进行丢包检测, 由于时间是
一个严格递增的量, 因此可以根据时间戳的不同 (如图 15 所示的 t 1 和 t 3 ) 来区分重传报文与原始报文. 如图 15 所
示, RACK 可以准确地识别重传报文的丢失情况.