拥塞现象是指对某资源的需求超过了该资源所能提供的可用部分,使网络性能变坏。
首先要说明对于拥塞的判断基于两点
1.重传定时器超时
2.收到3个重复的ACK(个别报文段在网络中丢失,预示可能会出现拥塞)
拥塞控制是防止过多的数据注入到网络中,使网络中的路由器或链路不致过载
TCP采用基于窗口的方法进行拥塞控制。
TCP拥塞控制算法可以分为四种,分别用于数据传输的不同阶段:
1.慢开始
2.拥塞避免
3.快重传
4.快恢复
先放上一个过程举例,在最后会讲到
慢开始:
用来确定网络的负载能力。
思路:由小到大逐渐增大拥塞窗口数值。
初始拥塞窗口cwnd设置:新的RFC 5681把初始拥塞窗口cwnd设置为不超过2至4个最大报文段SMSS数值的大小。
慢开始门限ssthresh(状态变量):防止拥塞窗口cwnd增长过大引起网络拥塞,是cwnd增长的上限,可以随着时间的变化而变化。
当我们发送的报文段的数量达到了慢开始门限ssthresh之后,就会由慢开始状态转入到拥塞避免状态。即:
•cwnd < ssthresh 使用慢开始算法
•cwnd > ssthresh 停止使用慢开始算法,改用拥塞避免算法
•cwnd = ssthresh 可使用慢开始算法,也可使用拥塞避免算法
拥塞窗口cwnd控制方法:在每收到一个对新的报文段的确认ACK时,实际上表明我们现在的网络状况是良好的,所有资源是够用的,那么可以把拥塞窗口增加最多一个SMSS的数值。
举例:
初始cwnd=1,发送方发送一个报文段M1,接收方收到后发送对M1的确认;发送方收到一个确认后,cwnd+1=2,之后发送两个报文段M2-M3,之后收到接收方发来的2个对报文段的确认后,cwnd+2=4,之后发送4个报文段M4-M7,之后收到接收方发来的4个对报文段的确认后,cwnd+4=8,以此类推。
意味着每经过一个传输轮次,拥塞窗口就加倍。(一个传输轮次所经历的时间是往返时间RTT)
在达到慢开始门限之前,发送方所能够发送的分组数是以指数级来增长的。既然是指数级增长,那么这意味着慢开始的过程并不慢,实际上指的是一开始的分组数量比较少,可以防止过多的分组短时间内传输到网络上导致拥塞。
拥塞避免:
拥塞避免并不是完全避免拥塞,而是让拥塞来得慢一些。
思路:当传输的报文数量达到上限ssthresh后,让拥塞窗口cwnd按线性规律缓慢增长,即每经过一个往返时间RTT就把发送方的cwdn加1,而非加倍。
而线性的增长也迟早会达到拥塞的程度。
当网络出现拥塞时:
无论是慢开始阶段,还是拥塞避免阶段,只要发送方判断网络出现拥塞(重传定时器超时):
•ssthresh=max(cwnd/2,2)
•cwnd=1
•执行慢开始算法(进入慢开始阶段)
目的是迅速减少主机发送到网络中的分组数,使发送拥塞的路由器有足够时间处理早队列中积压的分组。
快重传和快恢复:
快重传和快恢复的目的,是为了防止因为报文段丢失重新进入慢开始的过程。基本的判断方式是是否连续3次收到对同一个报文的ACK。
当收到3个重复的ACK,意味着我们对同一个报文重传了3次,并且对这3次都进行了确认。但这个时刻并不意味着发生了拥塞,所以要防止重新进入到慢开始阶段。
快重传:
可以让发送方尽快知道发生了个别报文段的丢失。
举例:
发送方发送M1数据报文段,接收方收到后发送对M1的确认;在确认M1到达前,发送方发送M2数据报文段,接收方收到后发送对M2的确认;在确认M2到达前,发送方发送M3数据报文段。
若M3在传输过程中丢失,接收方未收到M3,便也不会发送对M3的确认;此时发送方继续发送M4,接收方收到后,发现数据报文段并非按序到达,便发送针对M2的重复确认,表明我希望收到M3;此后发送方继续发送M5和M6数据报文段,接收方收到M5,M6,会第2次和第3次发送对M2的重复确认。这时发送方收到了3个连续的对M2的重复确认,便立即重传M3。
由于发送方收到3个重复的ACK,便知道只是丢失了个别报文段,认为网络很可能没有发生拥塞,因此不启动慢开始算法,而执行快恢复算法。
快恢复:
•慢开始门限ssthresh = 当前拥塞窗口cwnd / 2
•新拥塞窗口cwnd = 慢开始门限ssthresh
•开始执行拥塞避免算法,是拥塞窗口cwnd缓慢地线性增大
回到举例的这个过程(例子中忽略接收窗口值,若考虑接收窗口值,则有发送窗口=min[拥塞窗口,接收窗口])
横坐标是传输轮次。
首先在TCP连接进行初始化时,将拥塞窗口置为1,慢开始门限值置为16个报文段,发送端的发送窗口不能超过cwnd和接收端窗口rwnd中的最小值。我们假定接收端窗口足够大,因此现在发送窗口的数值等于cwnd数值。
在执行慢开始算法时,cwnd=1,发送第一个报文段,之后cwnd随着传输轮次按指数规律增长,cwnd=2,4,8,16。
当cwnd=16=ssthresh时,在点1改为执行拥塞避免算法,cwdn开始按线性规律增长,cwdn=17,18,19,20,21,22,23,24。
当cwnd=24时,在点2,网络出现了超时,发送方判断为网络拥塞。于是ssthresh调整为cwnd/2=12,同时cwnd=1,进入慢开始阶段。
之后cwnd=2,4,8,当cwnd=12时,改为执行拥塞避免算法。
cwnd=13,14,15,16,在点4,发送方收到3个重复的确认(图中记为3-ACK),发送方改为快重传和快恢复算法:调整ssthresh=cwnd/2=8,cwnd=ssthresh=8,开始执行拥塞避免算法。
总结:
在慢开始阶段,当cwnd指数级增长到达给定ssthresh值,进入拥塞控制阶段,cwnd开始线性增长。
之后有两种情况:
当出现超时,已经发生了网络拥塞,重新进入慢开始阶段,同时更改ssthresh=max(cwnd/2,2),更改cwnd=1。
当出现3-ACK,预示可能会出现拥塞,但现在还没有发生,于是进入快重传和快恢复阶段,更改ssthresh=cwnd/2,cwdn=ssthresh,之后进入拥塞控制阶段。
补充:
在拥塞避免阶段,拥塞窗口cwnd按照线性规律增大,这常称为“加法增大”AI
当出现超时或3个重复的确认时,将ssthresh门限值设置为当前拥塞窗口的一半,这常称为“乘法减小”MD
二者合在一起便是所谓的AIMD算法