拥塞控制原理
出现拥塞的原因无非是 对资源的需求>可用资源。
如果一个路由器没有足够的缓存空间,他就会丢弃一些新到的分组,导致发送该分组的发送方重传这一分组,甚至还可能重传多次,这样会引起更多的分组流入网络中和被路由器丢弃。课件拥塞引起的重传并不能很好地解决问题,反而使拥塞更为严重!
拥塞控制和流量控制的区别:
- 拥塞控制从群体利益出发,更像是一个设备问题,涉及大所有的主机、所有的路由器,控制网络的负载。(发送方不要发送的太快以至于网络处理不了)
- 流量控制从个体利益出发,实现可靠的数据传输(发送方不要发送的太快以至于接收方处理不了)
TCP拥塞控制
TCP使用的是端到端的拥塞控制(IP层并不会显示提供网络拥塞反馈)。TCP采用的是让每一个发送方根据所感知到的网络拥塞程度来限制其发送速率。
TCP采用基于窗口的方法进行拥塞控制。TCP发送方维持一个拥塞窗口swnd。该窗口的大小取决于网络的拥塞程度,并且动态的在变化。
真正的发送窗口值 = min{ 接收窗口 ,拥塞窗口 }
控制拥塞窗口的原则:
- 网络无拥塞时,窗口可以增大以便更多的分组发送出去,提高网络的利用率
- 网络出现拥塞时,就要适当减小窗口,以来缓解网络拥塞
拥塞判断:
- timeout
- 收到3个重复的ACK
下面我们来讨论关于TCP拥塞控制算法的四个主要部分:慢启动、拥塞避免、快速重传、拥塞恢复。
慢启动
当一条TCP连接开始时,cwnd(拥塞窗口)的值从一个MSS(Maximum Segment Size)开始,每当一个报文段首次被确认,cwnd就增加一个MSS。在这个过程中,每次经过一个RTT,cwnd的长度就翻倍。因此,在慢启动阶段,发送速度起始慢,但成指数级增长。
那么 我们下一个关心的问题一定是 何时结束这种指数级的增长呢?
—)发生Timeout事件时:TCP发送方将cwnd的值置为1并重新开启慢启动过程,且将ssthresh(慢启动阀值)设置为cwnd/2
—)发生3个冗余的ACK时:TCP执行快速重传并进入快速恢复的状态
—)当cwnd的值达到ssthresh时:结束慢启动并进入到拥塞避免模式
问题又来了:为什么面对timeout和3个重复ACK事件的处理方式不一致?
—)当发送方检测到个重复的ACK时,表示网络还能传输一些segment;但发生timeout事件时毫无疑问网络拥塞的程度更为严重
拥塞避免
让cwnd缓慢的增大,即当进入拥塞避免状态时,每经过一个RTT,cwnd的值只增加一个MSS。TCP逐渐增加发送速率,谨慎探测可用带宽,直到发生loss。
何时结束拥塞避免的线性增长?
发生timeout时:
- ssthresh = max(cwnd/2,2)
- cwnd=1
- 执行慢开始算法
收到3个冗余ACK时:ssthresh值记录为cwnd的一半,进入快速恢复状态
快速重传
采用快速重传算法可以让发送尽早知道发送了个别报文段的丢失
发送方只要一连收到三个重复的ACK,就立即重传,这样就不会出现超时,发送方也不会误以为出现了网络拥塞
拥塞恢复
当发送端收到连续三个重复的ACK时,认为网络很可能没有发生拥塞,因此不执行慢启动算法,而是执行拥塞恢复算法:
- ssthresh = 当前cwnd / 2
- cwnd = ssthresh
- 进入拥塞避免阶段,使得cwnd线性增长
总结一下
- 当 cwnd < ssthresh 时,发送方处于慢启动,cwnd呈指数增长
- 当 cwnd >= ssthresh 时,发送方处于拥塞避免状态,cwnd呈线性增长
- 当收到3个冗余的ACK时,ssthresh = cwnd / 2 , cwnd = ssthresh
- 当timeout时,ssthresh = cwnd / 2 , cwnd = 1