能导致网络拥塞的数据量称为拥塞点.

  • 网络设备不知道自己的拥塞点
  • 即使知道也不能通知发送方

如何避免触碰拥塞点?

方案1. 能否以发送方网卡带宽作为该连接的拥塞点?

  • 不能. 网络上不同设备的带宽不同

方案2: 逐步增加发送量, 直到网络发生拥塞, 这样得到的最大发送量是该连接的拥塞点吗?

  • 不是, 拥塞点是个动态值, 随网络流量的变化而变化

没有完美方案.

拥塞窗口

原理

靠谱的方案:

在发送方维护一个虚拟的拥塞窗口, 并利用各种算法使它尽可能接近真实的拥塞点. **网络对发送窗口的限制, 就是通过拥塞窗口实现的.

如何维护拥塞窗口:

  1. 连接刚建立的时候使用较小值, RFC 建议2~4个 MSS
  2. 初始时发生拥塞的概率比较低, 所以应该快速增大窗口
    1. 每收到 n 个确认就增加 n 个 MSS
    2. 2 + 2 = 4 (初始为2), 4 + 4 = 8, 8 + 8 = 16 …
    3. 由于基数低, 传输速度还是比较慢, 所以称为慢启动过程
  3. 当一段时间过后, 拥塞窗口达到一个较大值, 这时需要缓慢增加
    1. RFC 建议每个往返时间增加1个 MSS
    2. 16 + 1 = 17, 17 + 1 = 18, 18 + 1 = 19 …
    3. 这个过程称为拥塞避免
    4. 可以结合接收窗口取较大值作为拥塞窗口

image.png

超时重传

  • RTO

image.png

多一道公式, 损失一半读者.

超时后需要调整拥塞窗口:

  • RFC 建议调到1个 MSS, 然后进入慢启动
  • RFC 5681 认为临界窗口大小为上一次发生拥塞时没被确认的数据量的1/2, 但不能小于2个 MSS

发生超时重传时拥塞窗口的变化:

image.png

在 Wireshark 中检查重传情况:

  • Analyze —> Expert Info Composite

image.png

seq=1458613 的 RTO 长达 1s:

image.png

快速重传

当发送方收到3个或以上重复确认 (Dup Ack) 时, 就意识到相应的包已经丢了, 从而立即重传它.

例子:

image.png

为什么要凑满3个?

  • 网络包会乱序, 乱序的包也会触发重复的 Ack
  • 一般乱序的包距离正确位置不远

image.png

如果在拥塞避免阶段发生了快速重传, 那么如何调整?

  • 因为后续包到达了, 说明网络并没有严重拥塞
  • RFC 5681
    • 临界窗口: 发生拥塞时, 还没被确认的数据量的1/2, 但不能小于2个 MSS
    • 拥塞窗口: 临界窗口 + 3个 MSS
    • 继续保留在拥塞避免阶段
    • 这个过程称为快速恢复

image.png

多个包丢失重传方案

image.png

方案1

2号包重传后, 后续包全部重传.

  • 效率低

方案2

  • NewReno

image.png

方案3

  • SACK

image.png

实例:

  • 991851~992460: 未收到
  • 992461~996175: 已收到

image.png

小结

image.png

image.png

image.png