学过网络相关课程的,都知道TCP中,有两个窗口:
- 滑动窗口(在我们的上一篇文章中有讲),接收方通过通告发送方自己的可以接受缓冲区大小(这个字段越大说明网络吞吐量越高),从而控制发送方的发送速度。
- 拥塞窗口,也就是本文要讲的。
概念
一个连接的TCP双端只是网络最边缘的两台主机,他们不知道整个网络是如何工作的,因此他们不知道彼此之间的有效吞吐量。因此,他们必须找到一种方法来确定它。我们称之为拥塞窗口 (CWND)。这是在我们必须停止并等待确认之前可以发送的字节数。
拥塞窗口是决定任何时候可以发出的字节数的因素之一。拥塞窗口由发送方维护,是阻止发送方和接收方之间的链路因流量过多而过载的一种手段。这不应与发送方维护的滑动窗口相混淆,滑动窗口的存在是为了防止接收方过载。拥塞窗口是通过估计链路上有多少拥塞来计算的。
拥塞窗口对于设备来说是本地的,并且永远不会在连接上共享,这与在每个段中发送的接收器窗口不同。在任何给定时间,设备最多可以发送由接收器窗口和拥塞窗口之间的最小值指定的字节数,如下面的公式所示:
transmittable bytes = min(cwnd, rwnd)
这意味着如果拥塞窗口小于接收窗口,则设备可以在等待确认之前传输多达拥塞窗口中定义的字节数。相反,如果接收窗口小于拥塞窗口,则设备可以在等待确认之前最多传输接收器窗口中定义的字节数。
拥塞窗口根据网络拥塞动态变化。每次未确认段时,都假定是由于网络拥塞。拥塞窗口随时间演变的方式被定义为一个算法,这取决于实现。我们现在将介绍最常见的一种。该算法遵循以下规则:
- 拥塞窗口从一个段的大小开始(大约 1KB)
- 定义了一个拥塞窗口阈值(ssthresh)
- 如果收到确认,并且当前拥塞窗口大小小于 ssthresh,则拥塞窗口加倍
- 如果收到确认,但拥塞窗口大于或等于 sshthresh,则拥塞窗口增加其初始值(例如 1KB)
- 如果一个段没有被确认从而触发重传,拥塞窗口就会减半并且 ssthresh 被放置在这个值
- 拥塞窗口不能大于接收器窗口
该规则中包括我们经常听过的几种算法:
- 慢启动(slow-start)
- 拥塞避免(congestion avoidance)
- 快速重传(fast retransmit)
- 快速恢复(fast recovery)
算法
通过