当我们谈论 TCP 时,我们经常谈论加法增加乘法减少。
我们特别建议针对丢包情况将拥塞窗口大小减小 2 倍。然而,我的想法是否正确,实际上有多种方法?
在 TCP-Tahoe 中我们实际上根本不做 AIMD。当我们超时或发生三次重复确认时,CWND 设置为 1,并且慢启动再次开始(注意这不是乘法减少)。
在 TCP-Reno 中,我们在三重 dup-ack 上设置 CWND := CWND/2,在超时时设置 CWND := 1。(注意只有第一个实例是乘法减少)
将 CWND 一分为二是称为快速恢复的过程的一部分,这是(也是唯一)实现 AIMD 的地方。
以上是否正确?因此,您能否从锯齿波中识别出 TCP 版本是 Tahoe 还是 Reno?说 Tahoe 不做 AIMD 是否正确?
你说的很对,我再详细解释一下:
任何 TCP 拥塞控制算法都从拥塞窗口大小cwnd = 1
MSS(最大分段大小,因为拥塞窗口大小按字节缩放)开始,然后根据收到的确认数量开始加法增加,直到达到慢启动阈值ssthresh,即初始通告的值窗口大小。
那么,让我们假设一下ssthresh = 8
。TCP根据cwnd = 1
是否收到确认开始发送第一个报文段,cwnd根据公式加上收到的确认数cwnd = cwnd + MSS
(这意味着拥塞窗口大小增加1个报文段)。
然后cwnd >= ssthresh
每次收到 ACK 时,按如下方式递增 cwnd:(cwnd = cwnd + MSS(MSS/ cwnd)
不要忘记 cwnd 以字节为单位)。因此,仅当所有段都已被确认时,cwnd 才会增加一个段(= MSS 字节),例如:
假设最后一个 cwnd 是 8。
cwnd = 8 + 1 * ( 1 / 8)
并重复 8 次(因为所有段都已被确认)。因此,在添加1 / 8
到 cwnd 8 次之后,结果是 1 MSS 添加到最后一个已知的 cwnd,即 8,即新的 cwnd 是 9。
慢启动算法
If cwnd < ssthresh then
Each time an Ack is received:
cwnd = cwnd + MSS
else /* cwnd >= ssthresh */
Each time an Ack is received :
cwnd = cwnd + MSS. MSS / cwnd
endif
Run Code Online (Sandbox Code Playgroud)
有两种方法可以检测丢失:
情况一:定时器超时
Reno 将 cwnd 降至 1,然后使用 ssthresh = last_cwnd / 2 重新初始化慢启动。
案例 2:3 个重复确认 Reno 执行以下操作:
对于这两种情况,Tahoe 总是将 cwnd 降至 1,然后使用 ssthresh = last_cwnd / 2 重新初始化慢启动。
因此,您能否从锯齿波中识别出 TCP 版本是 Tahoe 还是 Reno?
TCP 拥塞算法始终在操作系统级别实现。Windows和Linux实现了以下算法(根据这篇论文):
说 Tahoe 不做 AIMD 是否正确?
Tahoe 只实现了 Additive Increase,没有实现 Multiplicative Decrease。里诺同时实现了它们。