TCP拥塞控制

TCP拥塞控制是传输控制协议（英语：Transmission Control Protocol，缩写TCP）避免网络拥塞的算法，是互联网上主要的一个拥塞控制措施。它使用一套基于线增积减模式的多样化网络拥塞控制方法（包括慢启动和拥塞窗口等模式）来控制拥塞。在互联网上应用中有相当多的具体实现算法。

运作方法

TCP使用多种拥塞控制策略来避免雪崩式拥塞。TCP会为每条连接维护一个“拥塞窗口”来限制可能在端对端间传输的未确认分组总数量。这类似TCP流量控制机制中使用的滑动窗口。TCP在一个连接初始化或超时后使用一种“慢启动”机制来增加拥塞窗口的大小。它的起始值一般为最大分段大小（Maximum segment size，MSS）的两倍，虽然名为“慢启动”，初始值也相当低，但其增长极快：当每个分段得到确认时，拥塞窗口会增加一个MSS，使得在每次往返时间（round-trip time，RTT）内拥塞窗口能高效地双倍增长。
当拥塞窗口超过慢启动阈值（ssthresh）时，算法就会进入一个名为“拥塞避免”的阶段。在拥塞避免阶段，只要未收到重复确认，拥塞窗口则在每次往返时间内线性增加一个MSS大小。

拥塞窗口

在TCP中，拥塞窗口（congestion window）是任何时刻内确定能被发送出去的字节数的控制因素之一，是阻止发送方至接收方之间的链路变得拥塞的手段。他是由发送方维护，通过估计链路的拥塞程度计算出来的，与由接收方维护的接收窗口大小并不冲突。
当一条连接创建后，每个主机独立维护一个拥塞窗口并设置值为连接所能承受的MSS的最小倍数，之后的变化依靠线增积减机制来控制，这意味如果所有分段到达接收方和确认包准时地回到发送方，拥塞窗口会增加一定数量。该窗口会保持指数增大，直到发生超时或者超过一个称为“慢启动阈值（ssthresh）”的限值。如果发送方到达这个阈值时，每收到一个新确认包，拥塞窗口只按照线性速度增加自身值的倒数。
当发生超时的时候，慢启动阈值降为超时前拥塞窗口的一半大小、拥塞窗口会降为1个MSS，并且重新回到慢启动阶段。
系统管理员可以设置窗口最大限值，或者调整拥塞窗口的增加量，来对TCP调优。
在流量控制中，接收方通过TCP的“窗口”值（Window Size）来告知发送方，由发送方通过对拥塞窗口和接收窗口的大小比较，来确定任何时刻内需要传输的数据量。

和式增加，积式减少

和式增加，积式减少（additive-increase/multiplicative-decrease，AIMD，这里简称“线增积减”）是一种反馈控制算法，其包含了对拥塞窗口线性增加，和当发生拥塞时对窗口积式减少。多个使用AIMD控制的TCP流最终会收敛到对线路的等量竞争使用。

快速重传

快速重传（Fast retransmit）是对TCP发送方降低等待重发丢失分段用时的一种改进。TCP发送方在每发送一个分段时会启动一个超时计时器，如果相应的分段确认没在特定时间内被送回，发送方就假设这个分段在网络上丢失了，需要重发。这也是TCP用来估计RTT的测量方法。
重复确认（duplicate cumulative acknowledgements，DupAcks）就是这个阶段的基础，其基于以下过程：如果接收方接收到一个数据分段，就会将该分段的序列号加上数据字节长的值，作为分段确认的确认号，发送回发送方，表示期望发送方发送下一个序列号的分段。但是如果接收方提前收到更下一个序列号的分段——或者说接收到无序到达的分段，即之前期望确认号对应的分段出现接收丢失——接收方需要立即使用之前的确认号发送分段确认。此时如果发送方收到接收方相同确认号的分段确认超过1次，并且该对应序列号的分段超时计时器仍没超时的话，则这就是出现重复确认，需要进入快速重传。
快送重传就是基于以下机制：如果假设重复阈值为3，当发送方收到4次相同确认号的分段确认（第1次收到确认期望序列号，加3次重复的期望序列号确认）时，则可以认为继续发送更高序列号的分段将会被接受方丢弃，而且会无法有序送达。发送方应该忽略超时计时器的等待重发，立即重发重复分段确认中确认号对应序列号的分段。

具体实现算法

“TCP+算法名称”这一TCP算法命名方式最早出在凯文·福尔（Kevin Fall）和莎莉·弗洛伊德（Sally Floyd）在1996年发布的一篇论文中。

快速恢复

快速恢复（Fast recovery）是Reno算法新引入的一个阶段，在将丢失的分段重传后，启动一个超时定时器，并等待该丢失分段包的分段确认后，再进入拥塞控制阶段。如果仍然超时，则回到慢启动阶段。

TCP Vegas

至1990年代中期，TCP量度延迟和RTT都是以传输缓存中最后一个被传送的分段包为准。亚利桑那大学的研究人员拉里·彼得森和劳伦斯·布拉科夫提出了新的TCP拥塞算法“TCP Vegas”，其实通过度量传输缓存中每个传送分段包来代替只量度一个分段包，通过每次度量的平均值来增加拥塞窗口。该算法取名自内华达州最大的城市拉斯维加斯。不过由于一些资源公平性原因，该算法并没有在彼得森的实验室之外广泛部署。一些研究认为该算法和其他拥塞算法混合使用，可能会导致性能竞争不及其他算法。在各种TCP拥塞算法的比较研究中，Vegas被认为是最平滑的控制算法，其次为CUBIC。
DD-WRT在v24 SP2开始将该算法作为其默认的TCP拥塞控制算法。

TCP New Reno

TCP New Reno是对TCP Reno中快速恢复阶段的重传进行改善的一种改进算法，其定义于RFC 6582，覆盖了原有在RFC 3782和RFC 2582的旧定义。
在Reno的快速恢复中，一旦出现3次重复确认，TCP发送方会重发重复确认对应序列号的分段并设置定时器等待该重发分段包的分段确认包，当该分段确认包收到后，就立即退出快速恢复阶段，进入拥塞控制阶段，但如果某个导致重复确认的分段包到遇到重复确认期间所发送的分段包存在多个丢失的话，则这些丢失只能等待超时重发，并且导致拥塞窗口多次进入拥塞控制阶段而多次下降。而New Reno的快速恢复中，一旦出现3次重复确认，TCP发送方先记下3次重复确认时已发送但未确认的分段的最大序列号，然后重发重复确认对应序列号的分段包。如果只有该重复确认的分段丢失，则接收方接收该重发分段包后，会立即返回最大序列号的分段确认包，从而完成重发；但如果重复确认期间的发送包有多个丢失，接收方在接收该重发分段后，会返回非最大序列号的分段确认包，从而发送方继续保持重发这些丢失的分段，直到最大序列号的分段确认包的返回，才退出快速恢复阶段。
New Reno在低错误率时运行效率和“选择确认”（Selective ACKnowledgement，SACK）相当，在高错误率仍优于Reno。

TCP Hybla

TCP Hybla旨在消除由于高延迟地面线路或者卫星无线链路下导致的RTT过长而对TCP链接的影响。它通过对拥塞窗口动态分析来修改，来减少对RTT的性能依赖。

TCP BIC 和 CUBIC

TCP BIC（Binary Increase Congestion control）旨在优化高速高延迟网络（即根据RFC 1072所定义的“长肥网络”（long fat network，LFN））的拥塞控制，其拥塞窗口算法使用二分搜索算法尝试找到能长时间保持拥塞窗口最大值的值。Linux内核在2.6.8至2.6.18使用该算法作为默认TCP拥塞算法。
CUBIC则是比BIC更温和和系统化的分支版本，其使用三次函数代替二分算法作为其拥塞窗口算法，并且使用函数拐点作为拥塞窗口的设置值。Linux内核在2.6.19后使用该算法作为默认TCP拥塞算法。

TCP Westwood和Westwood+

TCP Westwood改良自New Reno，不同于以往其他拥塞控制算法使用丢失来测量，其通过对确认包测量来确定一个“合适的发送速度”，并以此调整拥塞窗口和慢启动阈值。其改良了慢启动阶段算法为“敏捷探测（Agile Probing）”，和设计了一种持续探测拥塞窗口的方法来控制进入“敏捷探测”，使链接尽可能地使用更多的带宽。Westwood+使用更长的带宽估计间隔和优化的滤波器来修正Westwood对ACK压缩场景对带宽估计过高的问题。通过以上改良，TCP Westwood系列算法在有线网络和无线网络的拥塞控制上获取平衡，尤其研究中针对于无线通信网络上。

Compound TCP

复合TCP（Compound TCP）是微软自己实现的TCP拥塞控制算法，通过同时维护两个拥塞窗口，来实现在长肥网络有较好的性能而又不损失公平性。该算法在Windows Vista和Windows Server 2008开始广泛部署，并通过补丁的方式回溯支持到Windows XP和Windows Server 2003。在Linux上也有一个旧版本的移植实现。

TCP PRR

TCP PRR（TCP Proportional Rate Reduction ）是旨在恢复期间提高发送数据的准确性。该算法确保恢复后的拥塞窗口大小尽可能接近慢启动阈值。在Google进行的测试中，能将平均延迟降低3~10%，恢复的超时减少5%。PRR算法之后作为Linux内核3.2版本的默认拥塞算法。

TCP BBR

TCP BBR（Bottleneck Bandwidth and Round-trip propagation time）是由Google设计，于2016年发布的拥塞算法。以往大部分拥塞算法是基于丢包来作为降低传输速率的信号，而BBR则基于模型主动探测。该算法使用网络最近出站数据分组当时的最大带宽和往返时间来创建网络的显式模型。数据包传输的每个累积或选择性确认用于生成记录在数据包传输过程和确认返回期间的时间内所传送数据量的采样率。该算法认为随着网络接口控制器逐渐进入千兆速度时，分组丢失不应该被认为是识别拥塞的主要决定因素，所以基于模型的拥塞控制算法能有更高的吞吐量和更低的延迟，可以用BBR来替代其他流行的拥塞算法，例如CUBIC。Google在YouTube上应用该算法，将全球平均的YouTube网络吞吐量提高了4%，在一些国家超过了14%。
BBR之后移植入Linux内核4.9版本，并且对于QUIC可用。