详解TCP流量控制和拥塞控制

重传机制

TCP常用的重传机制:

  • 超时重传
  • 快速重传
  • SACK
  • D-SACK

超时重传

两种情况会触发:数据包丢失确认应答丢失

面临的问题是:重传时间可能较长

image-20240718152137733

快速重传

Seq2丢失后,后续发送Seq3、4、5的时候,都是返回了ACK2,当返回三个相同ACK的时候,会在定时器过期前,重传丢失的报文段。

但是这种方法目前面临的问题是:重发报文不是重发一个还是那个往后所有的。

image-20240718152403718

SACK

在TCP头部字段中加一个SACK的东西,它可以将已收到的数据的信息发送给发送方,这样发送发就知道哪些数据收到了,哪些数据没有收到,这样就可以只重传丢失的数据

这样就解决了快速重传中面临的问题了

1

D-SACK

使用场景:

  1. ACK丢包

接收方的ACK应答丢失了,发送方以为没发出去,就重发了,于是接收方收到重复数据后,告诉发送方真相

1

  1. 网络延迟

因为网络延迟,没有收到确认ACK。当重复传输的时候,告诉发送方,真正的原因

1

滑动窗口

发送窗口

image-20240718150744696

接收窗口

1

流量控制

防止发送方发送的数据超过接收方的处理能力,避免填满接收方的缓存区,从而导致数据丢失

image-20240718142647742

当窗口大小为0时,会阻止发送方给接收方发送数据,直到窗口变为非0

这时,如果接收方出现了缓存区,但是告诉发送方时候,ACK丢失了,那么发送方将一直不知道窗口大小可以变了吗?

为了解决这个问题,发送方当发现窗口为0的时候,会每隔一段时间发送一个1字节的报文去试探接收方是否还有空间

  • 如果接收窗口仍然为0,则接收重新启动计时器
  • 如果不为0,那接收方会得到新的窗口大小,重新开始传输数据

image-20240718142906639

拥塞控制

防止发送方的数据填满网络,避免网络中的路由器和链路过载,从而导致网络拥塞和性能下降

引入一个拥塞窗口(cwnd)的概念:

  • 只要网络中没有出现拥塞,cwnd 就会增大;
  • 但网络中出现了拥塞,cwnd 就减少;

发送方只要没有在规定时间内收到ACK,就会触发重传机制。那就可以理解为发生拥塞了

1. 慢启动

慢启动就是慢慢增加发送数据包的数量。也可以理解为,发送方每收到一个ACK,拥塞窗口cwnd大小就+1

有一个叫慢启动门限 ssthresh (slow start threshold)状态变量。

  • cwnd < ssthresh 时,使用慢启动算法。
  • cwnd >= ssthresh 时,就会使用「拥塞避免算法」。

1

2. 拥塞避免算法

拥塞窗口 cwnd 「超过」慢启动门限 ssthresh 就会进入拥塞避免算法。

一般来说 ssthresh 的大小是 65535 字节。

开始进入线性增长阶段。这么一直增长后,网络就会逐渐进入阻塞的状况了

image-20240718163818449

3. 拥塞发生

当网络出现拥塞,也就是会发生数据包重传,重传机制主要有两种:

  • 超时重传
  • 快速重传

当发生了「超时重传」,则就会使用拥塞发生算法。

这个时候,ssthresh 和 cwnd 的值会发生变化:

  • ssthresh 设为 cwnd/2
  • cwnd 重置为 1 (是恢复为 cwnd 初始化值,我这里假定 cwnd 初始化值 1)

1

但是这种方式太激进,容易产生网络卡顿。

还有更好的方式,前面我们讲过「快速重传算法」。当接收方发现丢了一个中间包的时候,发送三次前一个包的 ACK,于是发送端就会快速地重传,不必等待超时再重传。

TCP 认为这种情况不严重,因为大部分没丢,只丢了一小部分,则 ssthreshcwnd 变化如下:

  • cwnd = cwnd/2 ,也就是设置为原来的一半;
  • ssthresh = cwnd;
  • 进入快速恢复算法

4. 快速恢复

快速重传和快速恢复算法一般同时使用,快速恢复算法是认为,你还能收到 3 个重复 ACK 说明网络也不那么糟糕,所以没有必要像 RTO 超时那么强烈。

正如前面所说,进入快速恢复之前,cwndssthresh 已被更新了:

  • cwnd = cwnd/2 ,也就是设置为原来的一半;
  • ssthresh = cwnd;

然后,进入快速恢复算法如下:

  • 拥塞窗口 cwnd = ssthresh + 3 ( 3 的意思是确认有 3 个数据包被收到了);
  • 重传丢失的数据包;
  • 如果再收到重复的 ACK,那么 cwnd 增加 1;
  • 如果收到新数据的 ACK 后,把 cwnd 设置为第一步中的 ssthresh 的值,原因是该 ACK 确认了新的数据,说明从 duplicated ACK 时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进入拥塞避免状态;
  • 24
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值