浅谈TCP 流量控制 与 拥塞窗口

1,579 阅读4分钟

流量控制

对于发送端与接收端而言,TCP 需要将发送的数据放到发送缓冲区,接收的数据放到接受缓冲区, 并且需要根据接收端的接受缓冲区大小来控制发送端数据的发送

滑动窗口

TCP就是通过滑动窗口来实现流量控制的, 滑动窗口又分为 接收窗口发送窗口 发送窗口 包含已发送但尚未确认 以及 未发送但可以发送的部分

简述流量控制过程

接收端每次接收到发送端发过来的数据报文后,会返回一个确认报文,此时,再确认报文内会返回一个接收端里接收缓冲区剩余内存大小,发送端接受到确认报文后,会根据接收端缓冲区大小来改变自己发送窗口的大小,这就是流量控制的一个过程。

当接受端缓冲区没有剩余内存后,发送端也会修改发送窗口为零,避免大规模丢包,造成极大的网络资源浪费,当接收端缓冲区有新的内存空出来后,会发送个通知报文去告诉发送方,发送方接到这个报文后,就会改变自己发送窗口大小,继续发送数据。

但是,如果这个通知报文由于某种网络原因丢失了,那么发送端会一直等待接收端发送非零窗口通知,接收端也会一直等待发送端的新数据,形成一种死锁状态,为避免这种情况,当接收窗口为零时,发送端会启动一个定时器,隔段时间就会向接受端请求当前接收缓冲区大小,以此来改变发送窗口大小。

拥塞控制

重要知识点:

  • 慢启动
  • 拥塞避免
  • 快速重传
  • 快速恢复

慢启动

TCP 发送的过程并不是一开始就是以最大速度发包,防止因为网络的不稳定导致大规模的丢包,所以TCP开始会比较保守的速度来慢慢适应当前网络,运作过程是,当发送端每接收一个传输轮次,拥塞窗口翻倍。但是发送端的发送能力毕竟有限,不可能让他一直增长下去(虽然说发送窗口是取拥塞窗口与接收窗口中较小值的),所以我们需要一个阈值(ssthresh ),到达这个阈值之后便会停止使用慢启动,转成使用拥塞避免算法。

Tips: 首次的慢启动门限值会是一个很大的值,然后再首次发送超时后将慢启动门限值设为当前拥塞窗口的一半,拥塞窗口值设为1,并且重新开始慢启动

拥塞避免

拥塞避免算法中每经历一次传输轮次,拥塞窗口不再翻倍增加,而是只增加1,来缓慢的逼近极限

快速重传

一种可以在重传计时器到时之前就进行重传的技术,如果接收端收到一个out of order的报文段时,TCP会立即产生一个ACK报文让发送端知道自己接受到一个乱序报文,并且会告诉自己想要接收到的报文的seq,当接收端连续接收到三个及以上的重复报文时,就会判定改报文丢失,并且会立即重传丢失的报文,不用等待计时器到时。

快速恢复

快速恢复算法认为你当前网络也没那么糟糕,还能收到后面三个或者更多的报文,没必要重新来一次慢启动那么猛,把拥塞窗口降低一点就可以了。

cwnd = cwnd /2; // 拥塞窗口变为原来的一般
ssthresh = cwnd; // 将慢启动门限设为当前拥塞窗口大小
// 设置完后拥塞窗口会使用拥塞避免的算法进行增加。 避免了一次慢启动,可以为资源加载节省不少时间

快速恢复问题

如果有多个包丢失,则会多次触发快速重传与快速恢复,多次降低慢启动门限值与拥塞窗口大小,降低传输效率

拥塞控制小结

其实快速重传与快速回复只是避免在拥塞不严重的情况下过大的减小拥塞窗口,导致TCP传输效率下降。