TCP/IP协议(六、tcp拥塞控制)

如前面所述,针对丢包情况,TCP采用的首要机制是重传,包括超时重传和快速重传。针对保证接收端的顺序问题和接收速率比较慢的问题,TCP采用了滑动窗口的机制。这两个可以往回看前两篇。今天说的情况是,当网络处于拥塞奔溃状态时,共用一条网络传输路径的多个TCP连接却需要重传更多的数据包。这就好比火上浇油,可想而知,结果只会更糟,所以我们今天讨论的是如何避免这个问题。

6.1 TCP拥塞控制

典型的TCP只有在断定拥塞发生的情况下,才会采取相应的行动。推断是否出现拥塞,通常看是否有丢包情况发生。在TCP中。丢包也被用作判断拥塞发生与否的指标。

6.1.1 减缓TCP发送

假如我们已经测试出当前网络比较拥塞了,那怎么去减缓TCP发送呢?在TCP头部设置了通知窗口大小字段,该数组是可以控制TCP发送端的速率的。如果控制的,可以看上一节,滑动窗口。

基于网络传输能力的估计,可以在发送端引入一个窗口控制变量,确保发送窗口大小不超过接收端接收能力和网络传输能力,所以TCP发送端发送速率等于接收速率和传输速率两者的最小值。(在前面的机制上又添加了网络传输速率)

反应网络传输能力的变量称为拥塞窗口,记作cwnd。因此,发送端实际窗口W就是接收端通知窗口awnd和拥塞窗口cwnd的较小着:
W = min(cwnd, awnd)

应该到这里大家都明白了,怎么减缓TCP发送吧,还是用到老知识。但是拥塞窗口怎么确定值呢?有待下面可以探讨。

6.1.2 慢启动

我们怎么去测试当前网络传输速率呢?目前最有效的方法,就是以越来越快的速率不断发送数据,直到出现数据包丢失(或网络拥塞)为止。如果以全速启动的话,会影响其他连接的传输性能,所以通常会有特定的算法来避免过快启动,直到稳定传输后才会运行相应的其他算法。

上面所说的以越来越快的速率不断发送数据,这种方法叫做慢启动。在什么情况下,会启用慢启动算法呢?

  • 一个新的TCP连接建立
  • 检测到由重传超时(RTO)导致的丢包
  • 发送端长时间处于空闲状态

先来看图,图比较直观
在这里插入图片描述
看完图是不是恍然大悟。但是初始窗口的带下呢?我们一般讨论的都是初始化窗口为1SMSS。SMSS为接收方的MSS和路径MTU两者中较小值。

上面的图是假设没有拥塞的情况下,每个ACK都有回复,所以发送窗口以指数的形式增长。

如果大量数据包发送导致网络拥塞,cwnd将大幅度减小(减少至原来的一半)。

6.1.3 拥塞避免

慢启动的过程中就是为了确立一个慢启动阈值。一旦达到阈值,就意味着可能有更多可用的传输资源。如果立即全部占用这些资源,可能又会导致网络拥塞。

为了得到更多的传输资源而不致影响其他连接传输,TCP实现了拥塞避免算法。

在这里插入图片描述
由图可以看出,拥塞避免阶段额增长是比较缓慢的,因为我们应该确实了慢启动阈值了,所以如果再想发包的话,就只能这种缓慢的增长了。

6.1.4 慢启动和拥塞避免如何选择

前面我们已经说过慢启动阈值,这个值跟cwnd的关系是决定采用慢启动还是拥塞避免的界限。

当cwnd<ssthresh(慢启动阈值),使用慢启动算法
当cwnd > ssthresh,需要执行拥塞避免

慢启动阈值不是固定的,而是随着时间改变的。它的只要目的是,在没有丢包发生的情况下,记住上一次最好的操作窗口值。当有重传情况发生,不管是超时重传,还是快速重传,都会更新ssthresh

ssthresh = max(在外数据值/2), 2*SMSS)  (16-1)

我们已经知道,如果出现了重传情况,TCP会认为操作窗口超出了网络传输能力范围。这是会将慢启动阈值减少到至当前窗口大小一半(在外数据值/2就是当前窗口的一半)但不小于2*SMSS。从而减少最优窗口估计值。

6.1.5 标准TCP

是不是看了上面说的选择还是不太懂,其实我也是,所以还是需要一个实例来屡屡思路。标准TCP就是一个很好的例子。

在TCP连接建立之初首先是慢启动阶段(cwnd=1SMSS),ssthresh通常取一个较大值(至少为awand)。当接收到一个好的ACK之后,cwnd会相应更新:(一般刚开始都是慢启动,等到接收端返回了很多ack之后,cwnd增长,一直增长到慢启动阈值之后,才会减缓增长,直到没有接收到ack)
cwnd += SMSS (若cwnd < ssthresh)慢启动
cwnd+= SMSS* SMSS/cwnd(若cwnd > ssthresh)拥塞避免

当收到三次重复ACk(或其他表面需要快速重传的信号)时,会执行一下行为:

  1. ssthresh更新为大于等于(16-1)中的值
  2. 启用快速重传算法,将cwnd设为(ssthresh+3*SMSS)
  3. 每接收一个重复ACK,cwnd值暂时增加1SMSS
  4. 当接收到一个好的ACK,讲cwnd重设为ssthresh

步骤2和步骤3构成了快速恢复。步骤2设置cwnd的大小,cwnd会见到之前值的一半+3SNSS,然后,考虑到每接收一个重复ACK,就意味着相应的数据包已成功传输,这时候新的数据可以发送了,所以cwnd的值会增加,直到接收到发送一个好的ACK之后,才会把cwnd重设为ssthresh,重新开始发送。

图就先别画了,我先用文字总结一下,有空再补补图

简单流程应该是这样的 :Tcp建立连接,开始慢启动,cwin会以1smss的速度增长或者以拥塞避免的方式增长; 直到遇到没有收到的ack包,cwin直接减为原来的的一半再加3SMSS;
如果这时候还是没接受到ack包,就还会往下减 ;
如果这时候能接受到ack包,cwin会暂时增加1SMSS;
如果网络变好就会一直往上加,出现了丢包就往下减, 以此循环。

还有TCP/IP协议有一些算法优化也还没看,以后有时间补补。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值