少而好学,如日出之阳;壮而好学,如日中之光;志而好学,如炳烛之光。——刘向
文章目录
- 拥塞控制方法
- ATM ABR拥塞控制
- TCP拥塞控制
- TCP拥塞控制算法的实现
- 慢启动
- 拥塞避免
- 快速恢复
- 总结
拥塞控制方法
在上一篇文章中,我们介绍了在数据传输过程中出现的问题。本节将简要介绍解决这些问题的方法。笼统来讲,根据网络层是否向运输层提供拥塞信息,我们可以将这些方法分为两类:
- 端到端拥塞控制:在这类方法中,运输层不能显式的从网络层获取拥塞信息,只能通过丢包,时延增加等迹象来推断发生拥塞。这是TCP协议采用的方法,因为IP协议不会向运输层报告拥塞。如果推断出有拥塞出现,TCP就会使用让窗口减小等方法控制拥塞。
- 网络辅助的拥塞控制:在这类方法中,网络层构件显式的向发送方主机运输层发送拥塞信息,这类信息可能是一个报文,也可能只是一个比特。路由器向发送方主机运输层发送信息的方式也有两种,可以直接向发送方主机发送报文,也可以先随要发送的数据发送到接收方,再由接收方发送到发送方。
在这里我们先简要介绍第二种方法,即网络辅助的拥塞控制。
ATM ABR拥塞控制
ATM采用面向虚电路(VC)的方法处理分组交换,这需要网络上的每台交换机维护从源到目的地VC的状态。这意味着每台交换机都掌握从整条链路和发送方主机的信息,非常适合用网络辅助的拥塞控制手段。
在ATM ABR中,封装数据的单位被称为信元而非分组。发送方在发送数据信元时,也会夹杂一些资源管理信元(RM信元)用于传递拥塞信息,这些RM信元在经过交换机或被接收方回送时可能会被修改。链路上的交换机也可以发送RM信元给发送方,这也体现了路由器反馈拥塞信息的两种方式。
对于反馈信息的第二种方式,即路由器将信息随数据发送给接收方,再由接收方回送,ABR提供了三种机制:
- EFCI比特:每个数据信元带有一个EFCI比特,如果网络处于拥塞状态,那么交换机将每一个经过的数据信元的EFCI比特置为1。如果接收方发现收到的大量数据信元的EFCI比特都是1,那么它将下一个RM信元的拥塞指示比特(CI比特)置为1并会送给发送方。
- CI比特和NI比特:RM信元中有拥塞指示(CI)比特和无增长(NI)比特。在轻微拥塞时,交换机将NI比特置为1;严重拥塞时,交换机将CI比特置为1。
- ER字段:RM信元中包含一个两字节的显式速率(ER)字段。每经过一个交换机,如果这个字段的值大于该交换机所在链路的可支持速率(比如该交换机处于拥塞状态),那么这个字段的值将被更新为改速率。最终ER字段被设置为从源到目的地的路径上所有交换机的最小可支持速率。
TCP拥塞控制
正如上文所说,TCP使用端到端拥塞控制。为了实现TCP拥塞控制算法,TCP拥塞控制机制在发送方增加一个变量,即拥塞窗口(cwnd),它与接收方的接收窗口(rwnd)共同作用。发送方中未被确认的数据量不能超过这两个值中的较小值:
如果rwnd无限大,这样未被确认的数据量就只受制于cwnd,进而cwnd就可以控制发送速率。粗略的来说,设往返时间为RTT,那么发送速率就是cwnd/RTT字节/秒。TCP中,有几条原则用以控制发送速率:
- 发生丢包时降低TCP发送方的速率。
- 有未确认报文段确认到达,即有报文顺利到达接收方时,增加TCP发送方速率,由于这条原则,TCP被称为自计时的。
TCP拥塞控制算法的实现
算法包括慢启动,拥塞避免,快速恢复三个部分。
慢启动
慢启动的目的是在连接开始时快速找到发送报文的合适速率。开始一段TCP连接时,拥塞窗口长度设为一个TCP报文长度(称为1个MSS),每收到一个新的确认报文,拥塞窗口增加1个MSS,这样可以达到每过一个RTT发送速率(拥塞窗口)翻倍的效果。例如,开始连接时窗口是一个MSS,发送一个TCP报文后等待确认报文,经过一个RTT,它收到确认,增加一个MSS,窗口长度变为2个MSS;然后它可以连续发送两个TCP报文,同理在一个RTT后它将收到两个确认报文,增加两个MSS,窗口长度变为4个MSS。通过这种方式,窗口长度得以指数式增长。
我们可以通过上面的FSM图看到关于慢启动状态转换条件的几种情况:
- 在一开始进入慢启动状态时进行初始化,将拥塞窗口长度设为1个MSS,ssthresh值(称为“慢启动阈值”,当拥塞窗口长度大于该值时转换为拥塞避免状态)设为64KB。dupACKcount值(收到的冗余ACK报文数量,当数量达到3时代表网络可能发生拥塞,转换到快速恢复状态)设为0.
- 收到冗余ACK报文时,dupACKcount值加1.
- 收到新的ACK报文时,拥塞窗口长度加1个MSS,同时TCP协议确认网络不拥塞,重置dupACKcount值。
- 超时时,确认发生拥塞且状况比较严重,将ssthresh值设为当前窗口长度的1/2(即TCP认为比较合适的发送速率),重置其他变量并重新开始慢启动过程。
- 当拥塞窗口长度大于sstresh值时,需要进行谨慎的速率增加,因此切换到拥塞避免状态。
- 冗余ACK报文数量到达3时,协议认为网络处于轻度拥塞状态,将sstresh值置为当前拥塞窗口长度的1/2并将新拥塞窗口长度置为sstresh值加3个MSS,切换到快速恢复状态。
拥塞避免
当TCP协议认为当前发送速率与适宜速率(充分利用链路资源且不会造成拥塞的速率)相近时,协议转换到拥塞避免状态以进行谨慎地速率增加。在这种状态下,每收到一个新确认报文,拥塞窗口长度增加MSS*MSS/cwnd字节,因此每经过一个RTT,拥塞窗口长度增加一个MSS,实现线性增长。
拥塞避免状态的转换条件:
- 收到一个新的确认报文时,按照上文所示增加拥塞窗口长度并将冗余ACK报文段的数量置为0(每次协议认为网络不处于拥塞状态时都会重置dupACKcount值)。
- 收到冗余ACK报文时,增加dupACKcount值
- 冗余ACK报文数量到达3时采取与慢启动相同的策略并切换到快速恢复状态。
- 超时时,重置所有变量,进入慢启动状态。
快速恢复
当协议认为网络处于轻度拥塞状态(协议收到3个冗余ACK报文)时,切换到快速恢复状态。快速恢复状态的状态转换条件:
- 接收到冗余ACK时,协议继续处于快速恢复状态,但为了保证发送速率且尽快切换到别的状态,协议继续增加拥塞窗口长度。
- 发生超时时,协议认为网络拥塞程度加重,重置变量并切换到慢启动模式(注意,除了第一次连接以外sstresh值都重置为cwnd的1/2)。
- 接收到新的ACK报文时,协议认为网络不再拥塞,将cwnd重置为sstresh值并重置dupACKcount值,切换到拥塞避免状态。
总结
由于在实践中,cwnd常处于线性增长阶段,且每次减少都置为1,故TCP拥塞控制算法称为加性增,乘性减。
我是霜_哀,在算法之路上努力前行的一位萌新,感谢你的阅读!如果觉得好的话,可以关注一下,我会在将来带来更多更全面的知识讲解!