TCP协议的秘密武器:流量控制与拥塞控制
TCP可靠性传输
相信大家都熟知TCP协议作为一种可靠传输协议,但它是如何确保传输的可靠性呢?
要实现可靠性传输,需要考虑许多因素,比如数据的损坏、丢失、重复以及分片顺序混乱等问题。如果不能解决这些问题,就无法实现可靠传输。
因此,TCP采用了序列号、确认应答、重发控制、连接管理和窗口控制等机制来实现可靠性传输。
在本文中,我们将重点介绍TCP的滑动窗口、流量控制和拥塞控制。重传机制将在下一章节单独讲解。
流量控制
流量控制实际上是生产者和消费者之间微妙关系的一个具体体现。你可能在工作中或者面试中经常遇到这种考察场景。如果生产者的生产能力大大超过消费者的消费能力,就会导致队列无限增长。更严重的情况是,你可能知道当RabbitMQ消息堆积过多时,会导致整个MQ服务器性能下降。TCP也是类似的道理,如果不加以控制,过多的消息都被放到网络中,消费者已经超过了其能力范围,而生产者仍在重复发送,这会大大影响网络传输性能。
为了解决这种现象,TCP提供了一种机制,让发送方根据接收方的实际接收能力来控制发送的数据量,这就是所谓的流量控制。接收方维护一个接收窗口,而发送方维护一个发送窗口。需要注意的是,这些窗口只针对单个TCP连接,而不是所有连接共享一个窗口。
TCP通过使用一个接收窗口的变量来提供流量控制。接收窗口给发送方一个指示,告诉它还有多少可用的缓存空间。发送端根据接收端的实际接受能力来控制发送的数据量。
接收端主机会通知发送端主机自己可以接收数据的大小,发送端会发送不超过这个限度的数据。这个大小限度就是窗口大小,你还记得TCP首部吗?有一个接收窗口字段,它用于指示接收方能够或愿意接收的字节数量。
发送端主机会定期发送一个窗口探测包,用于探测接收端主机是否还能够接受数据。当接收端的缓冲区面临数据溢出的风险时,窗口大小的值也会相应地被设置为一个更小的值,通知发送端控制数据发送量。
以下是一个流量控制示意图:

为了确保接收端主机能够及时处理数据,发送端主机会根据接收端主机的窗口大小进行流量控制。这样可以防止发送端主机一次发送过大的数据导致接收端主机无法处理。
如上图所示,假设主机B的缓冲区已经满了,在接收到报文段2000-2999之后,它不得不暂停接收数据。为了解决这个问题,主机A会发送窗口探测包,这个包非常小,只有一个字节。主机B会根据接收缓冲区的情况更新接收窗口大小,并发送窗口更新通知给主机A。然后主机A可以继续发送报文段。
在上述发送过程中,窗口更新通知有可能会丢失。一旦丢失,发送端就不会继续发送数据。为了避免这种情况发生,窗口探测包会被随机发送,以确保通知的可靠传输。
拥塞控制
在介绍拥塞控制之前,我们需要了解除了接收窗口和发送窗口之外,还有一个拥塞窗口,它主要用于解决发送方以什么速度开始发送数据给接收窗口的问题。因此,拥塞窗口也是由TCP发送方进行维护的。我们需要一个算法来决定发送多少数据是合适的,因为发送数据过少或过多都不理想,所以就有了拥塞窗口的概念。
在之前的流量控制中,我们避免的是发送方的数据填满接收方的缓存,但是我们并不知道网络中发生了什么情况。通常情况下,计算机网络处于一个共享的环境中。因此,可能会因为其他主机之间的通信而导致网络拥堵。
当网络出现拥堵时,如果继续发送大量数据包,可能会导致数据包的延迟和丢失等问题。此时,TCP会重传数据,但是重传会增加网络的负担,导致更大的延迟和更多的丢包。这种情况会进入恶性循环,并不断放大。
因此,TCP不能忽略网络上发生的情况。当网络发生拥塞时,TCP会自我牺牲,降低发送的数据量。
因此,拥塞控制就应运而生,其目的是避免发送方的数据填满整个网络。为了调节发送方应该发送的数据量,所以TCP定义了一个叫做拥塞窗口的概念。拥塞控制的算法会根据网络的拥塞程度来调整拥塞窗口的大小,从而控制发送方的数据量。
什么是拥塞窗口?和发送窗口有什么关系呢?
拥塞窗口(Congestion Window)是发送方维护的一个状态变量,它决定了发送方可以发送的数据量。拥塞窗口会根据网络的拥塞程度动态变化。
发送窗口(Sending Window)是发送方和接收方之间约定的一个窗口大小,表示接收方可以接收的数据量。拥塞窗口和发送窗口有关系,发送窗口的值通常等于拥塞窗口和接收窗口中的最小值,即swnd = min(cwnd, rwnd)。
拥塞窗口cwnd的变化规则如下:
如果网络中没有出现拥塞,即没有发生超时重传,拥塞窗口会增大;
如果网络中出现了拥塞,拥塞窗口会减小。
发送方通过观察是否在规定时间内收到ACK确认报文来判断网络是否出现了拥塞。如果发送方在规定时间内没有收到ACK确认报文,就认为网络出现了拥塞。
除了拥塞窗口,下⾯我们就该聊⼀下 TCP 的拥塞控制算法(TCP congestion control algorithm) 了。TCP 拥塞控制算法主要包含三个部分:
- 慢启动(Slow Start):初始时,拥塞窗口cwnd的值比较小,发送方以指数增加的方式增大拥塞窗口,以快速适应网络的容量。
- 拥塞避免(Congestion Avoidance):拥塞窗口超过一定阈值后,发送方以线性增加的方式增大拥塞窗口,以减缓拥塞窗口的增长速度,避免过载网络。
- 快速恢复(Fast Recovery):如果发生拥塞,发送方将拥塞窗口减半,并进入快速恢复状态,通过接收到的重复ACK来确定网络恢复的位置,然后继续增加拥塞窗口。
慢启动
当一条TCP连接建立时,拥塞窗口cwnd的初始值会设为一个MSS(最大报文段长度)的较小值。这样,初始的发送速率大约是MSS/RTT(往返时间)字节/秒。实际可用带宽通常比MSS/RTT大得多,因此TCP希望找到最佳的发送速率,可以通过慢启动的方式来实现。
在慢启动过程中,拥塞窗口cwnd的值会初始化为1个MSS,并且每次传输的报文段确认后,cwnd的值会增加一个MSS,即cwnd的值会变为2个MSS。之后,每成功传输一个报文段,cwnd的值就会翻倍,依此类推。具体的增长过程如下图所示。

然而,发送速率不可能一直增长,增长总有结束的时候。那么,何时结束发送速率的增长呢?慢启动通常会使用以下几种方式来结束发送速率的增长。
第一种方式是在慢启动的发送过程中出现丢包的情况。当发生丢包时,TCP会将发送方的拥塞窗口cwnd设置为1,并重新开始慢启动的过程。此时,引入了一个慢启动阈值ssthresh的概念,它的初始值就是产生丢包的cwnd的值的一半。也就是说,当检测到拥塞时,ssthresh的值就是窗口值的一半。
第二种方式是直接和慢启动阈值ssthresh的值相关联。因为当检测到拥塞时,ssthresh的值就是窗口值的一半,那么当cwnd大于ssthresh时,每次翻番都可能会出现丢包。所以,最好的方式就是将cwnd的值设为ssthresh,这样TCP就会转为拥塞控制模式,结束慢启动。
慢启动结束的最后⼀种⽅式就是如果检测到 3 个冗余 ACK,TCP 就会执⾏⼀种快速重传并进⼊恢复状态。(如果不清楚为什么会有三次同样的ACK报文,在重传机制中会单独讲解)
拥塞避免
当TCP进入拥塞控制状态后,cwnd的值会被设为拥塞阈值ssthresh的一半。这意味着无法每次收到报文段后都将cwnd的值翻倍。相反,采用了一种相对保守的方式,即每次传输完成后,只将cwnd的值增加一个MSS(最大报文段长度)。例如,即使收到了10个报文段的确认,但cwnd的值只会增加一个MSS。这是一种线性增长模式,它也有一个增长上限。当出现丢包时,cwnd的值将变为一个MSS,ssthresh的值将设为cwnd的一半;或者当收到3个冗余的ACK响应时,也会停止MSS的增长。如果在将cwnd的值减半后仍然收到3个冗余ACK,那么ssthresh的值将记录为cwnd值的一半,并进入快速恢复状态。
快速恢复
在快速恢复(Fast Recovery)状态中,对于每个收到的冗余ACK(即不是按顺序到达的ACK),拥塞窗口cwnd的值会增加一个MSS。这是为了利用网络中已经传输成功的报文段,尽可能地提高传输效率。
当丢失的报文段的一个ACK到达时,TCP会降低cwnd的值,然后进入拥塞避免状态。这是为了控制拥塞窗口的大小,避免继续加重网络拥塞。
如果在拥塞控制状态后出现超时,说明网络状况变得更加严重,TCP会从拥塞避免状态迁移到慢启动状态。此时,拥塞窗口cwnd的值被设置为1个MSS(最大报文段长度),而慢启动阈值ssthresh的值被设置为cwnd的一半。这样做的目的是为了在网络恢复后,重新逐渐增加拥塞窗口的大小,以平衡传输速率和网络拥塞程度。
总结
TCP协议作为一种可靠传输协议,通过序列号、确认应答、重发控制、连接管理和窗口控制等机制来实现可靠性传输。其中,流量控制机制通过发送方根据接收方的实际接收能力来控制发送的数据量,避免了网络拥堵和性能下降的问题。而拥塞控制机制则通过调节发送方的数据发送量,避免了网络拥塞的发生。拥塞窗口和发送窗口的概念相互关联,通过动态调整拥塞窗口的大小来控制发送方的数据量。慢启动、拥塞避免和快速恢复是TCP拥塞控制算法的三个主要部分,通过不同的策略来调节拥塞窗口的大小,以适应网络的容量和拥塞程度。
在下一章节中,我们将详细讲解TCP的重传机制。重传机制是TCP实现可靠传输的重要组成部分,通过对丢失、损坏或延迟的数据进行重传,确保数据的可靠性传输。重传机制的实现原理和策略将在下一章节中进行详细的介绍和解析。敬请期待!
TCP协议的秘密武器:流量控制与拥塞控制的更多相关文章
- TCP协议的滑动窗口协议以及流量控制
参考资料 http://blog.chinaunix.net/uid-26275986-id-4109679.html http://network.51cto.com/art/201501/4640 ...
- TCP的流量控制与拥塞控制小结
概述 为了提高信道的利用率TCP协议不使用停止等待协议,而是使用连续ARQ协议,意思就是可以连续发出若干个分组然后等待确认,而不是发送一个分组就停止并等待该分组的确认.其中TCP的流量控制与拥塞控制是 ...
- TCP基础知识(三)重传、流量控制、拥塞控制
TCP详解(3):重传.流量控制.拥塞控制…… 数据传输 在TCP的数据传送状态,很多重要的机制保证了TCP的可靠性和强壮性.它们包括:使用序号,对收到的TCP报文段进行排序以及检测重复的数据:使用校 ...
- TCP的可靠传输(依赖流量控制、拥塞控制、连续ARQ)
TCP可靠性表现在它向应用层提供的数据是无差错,有序,无丢失,即递交的和发送的数据是一样的. 可靠性依赖于流量控制.拥塞控制.连续ARQ等技术 <TCP/IP详解>中的“分组”是不是就是报 ...
- 运输层7——TCP的流量控制和拥塞控制
目录 1. TCP的流量控制 2. TCP的拥塞控制 写在前面:本文章是针对<计算机网络第七版>的学习笔记 运输层1--运输层协议概述 运输层2--用户数据报协议UDP 运输层3--传输控 ...
- TCP 的三次握手和四次挥手,TCP 的流量控制和拥塞控制
70.TCP协议的三次握手与四次挥手70.1.TCP报文结构 1.源端口号:表示发送端端口号,字段长为16位. 2.目标端口号:表示接收端口号,字段长为16位. 3.序列号:表示发送数据的位置 ...
- 【图解】你还在为 TCP 重传、滑动窗口、流量控制、拥塞控制发愁吗?看完图解就不愁了
每日一句英语学习,每天进步一点点: 前言 前一篇「硬不硬你说了算!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题」得到了很多读者的认可,在此特别感谢你们的认可,大家都暖暖的. 来了,今 ...
- TCP 重传、滑动窗⼝、流量控制、拥塞控制
重传机制 TCP 会在以下两种情况发⽣超时重传: 数据包丢失 确认应答丢失 重传超时 重传超时是TCP协议保证数据可靠性的另一个重要机制,其原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果 ...
- TCP流量控制与拥塞控制
为了更好地对传输层进行拥塞控制,因特网建议标准定义了以下四种算法:慢启动.拥塞避免.快重传和快恢复. 1 接收窗口rwnd与拥塞窗口cwnd 发送方在确定发送报文段的速率时,既要根据接收方的接收能力, ...
- TCP/IP笔记 三.运输层(2)——TCP 流量控制与拥塞控制
TCP 的流量控制与拥塞控制可以说是一体的.流量控制是通过滑动窗口实现的,拥塞避免主要包含以下2个内容: (1)慢开始,拥塞避免 (2)快重传,快恢复 1.流量控制——滑动窗口 TCP采用大小可变的滑 ...
随机推荐
- STM32F429 Discovery开发板应用:实现SPI-SD Card文件写入(搭载FatFS文件系统)
MCU:STM32F429ZIT6 开发环境:STM32CubeMX+MDK5 外购了一个SPI接口的SD Card模块,想要实现SD卡存储数据的功能. 首先需要打开STM32CubeMX工具.输入开 ...
- global average pooling
首先需要对深度网络中常见的pooling方式,以及全连接层有大致的了解.(此处略过不提.) paper: Network in Network fully connected layer 的缺点 在N ...
- 1 大数据实战系列-spark+hadoop集成环境搭建
1 准备环境 192.168.0.251 shulaibao1 192.168.0.252 shulaibao2 hadoop-2.8.0-bin spark-2.1.1-bin-hadoop2.7 ...
- 基于百度AI平台的人脸识别评分小程序
face-recognition-scoring-applet 开放源代码,遵循Apache License 2.0 效果展示 可切换摄像头.拍照.从相册选择 效果预览 小程序账号注册及配置 地址:h ...
- 瞬间抠图!揭秘 ZEGO 绿幕抠图算法背后的技术
抠图是图像处理中最常见的操作之一,指的是将图像中需要的部分从画面中精确的提取出来. 抠图的主要功能是为了后期的合成做准备.在 Photoshop 中,抠图的方法有很多种,最常见的有通道抠图.蒙版抠图. ...
- Java扩展Nginx之七:共享内存
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 作为<Java扩展Nginx>系 ...
- quarkus实战之六:配置
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<quarkus实战>系列 ...
- 2021-8-5 Mysql个人练习题
创建学校表格 CREATE TABLE `Student`( `s_id` VARCHAR(20), `s_name` VARCHAR(20) NOT NULL DEFAULT '', `s_birt ...
- QLabel标签快捷键的使用
1 from PyQt5.QtWidgets import * 2 import sys 3 4 class QlabelDemo(QDialog): 5 def __init__(self): 6 ...
- VBA与VB的区别
从语言结构上讲,VBA是VB的一个子集,它们的语法结构是一样的.两者的开发环境也几乎相同.但是,VB是独立的开发工具,它不需要依附于任何其他应用程序,它有自己完全独立的工作环境和编译.链接系统.VBA ...