TCP协议的秘密武器:流量控制与拥塞控制

简介: 本文将深入探讨TCP协议的关键机制,包括流量控制和拥塞控制,以解密其在网络数据传输中的作用。通过了解TCP协议的工作原理,我们可以更好地理解网络通信的稳定性和可靠性,为我们的网络体验提供更安全、高效的保障。无论您是网络爱好者、技术从业者还是普通用户,本文将为您揭开TCP协议的神秘面纱,带您进入网络传输的奇妙世界。

TCP可靠性传输

相信大家都熟知TCP协议作为一种可靠传输协议,但它是如何确保传输的可靠性呢?

要实现可靠性传输,需要考虑许多因素,比如数据的损坏、丢失、重复以及分片顺序混乱等问题。如果不能解决这些问题,就无法实现可靠传输。

因此,TCP采用了序列号、确认应答、重发控制、连接管理和窗口控制等机制来实现可靠性传输。

在本文中,我们将重点介绍TCP的滑动窗口、流量控制和拥塞控制。重传机制将在下一章节单独讲解。

流量控制

流量控制实际上是生产者和消费者之间微妙关系的一个具体体现。你可能在工作中或者面试中经常遇到这种考察场景。如果生产者的生产能力大大超过消费者的消费能力,就会导致队列无限增长。更严重的情况是,你可能知道当RabbitMQ消息堆积过多时,会导致整个MQ服务器性能下降。TCP也是类似的道理,如果不加以控制,过多的消息都被放到网络中,消费者已经超过了其能力范围,而生产者仍在重复发送,这会大大影响网络传输性能。

为了解决这种现象,TCP提供了一种机制,让发送方根据接收方的实际接收能力来控制发送的数据量,这就是所谓的流量控制。接收方维护一个接收窗口,而发送方维护一个发送窗口。需要注意的是,这些窗口只针对单个TCP连接,而不是所有连接共享一个窗口。

TCP通过使用一个接收窗口的变量来提供流量控制。接收窗口给发送方一个指示,告诉它还有多少可用的缓存空间。发送端根据接收端的实际接受能力来控制发送的数据量。

接收端主机会通知发送端主机自己可以接收数据的大小,发送端会发送不超过这个限度的数据。这个大小限度就是窗口大小,你还记得TCP首部吗?有一个接收窗口字段,它用于指示接收方能够或愿意接收的字节数量。

发送端主机会定期发送一个窗口探测包,用于探测接收端主机是否还能够接受数据。当接收端的缓冲区面临数据溢出的风险时,窗口大小的值也会相应地被设置为一个更小的值,通知发送端控制数据发送量。

以下是一个流量控制示意图:

image

为了确保接收端主机能够及时处理数据,发送端主机会根据接收端主机的窗口大小进行流量控制。这样可以防止发送端主机一次发送过大的数据导致接收端主机无法处理。

如上图所示,假设主机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的值就会翻倍,依此类推。具体的增长过程如下图所示。

image

然而,发送速率不可能一直增长,增长总有结束的时候。那么,何时结束发送速率的增长呢?慢启动通常会使用以下几种方式来结束发送速率的增长。

第一种方式是在慢启动的发送过程中出现丢包的情况。当发生丢包时,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实现可靠传输的重要组成部分,通过对丢失、损坏或延迟的数据进行重传,确保数据的可靠性传输。重传机制的实现原理和策略将在下一章节中进行详细的介绍和解析。敬请期待!

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
存储 关系型数据库 MySQL
【MySQL专题】MySQL百万级数据插入效率优化
【MySQL专题】MySQL百万级数据插入效率优化
1233 0
【MySQL专题】MySQL百万级数据插入效率优化
|
11月前
|
存储 Linux Docker
docker在欧拉服务器上编译安装应该注意什么?如何操作?
【10月更文挑战第31天】docker在欧拉服务器上编译安装应该注意什么?如何操作?
389 2
|
网络协议 算法 网络性能优化
【TCP】核心机制:滑动窗口、流量控制和拥塞控制
【TCP】核心机制:滑动窗口、流量控制和拥塞控制
275 2
|
机器学习/深度学习 人工智能 机器人
人工智能与自动化:重塑未来工作场景
【8月更文第8天】随着技术的飞速发展,人工智能(AI)和自动化已成为推动各行各业变革的关键力量。这些技术不仅提高了生产效率,还为传统工作岗位带来了新的活力,并创造出了许多全新的职业领域。本文将探讨AI和自动化如何重塑工作场景,并通过具体的编程示例来展示如何利用这些技术。
428 1
|
Web App开发 Linux 微服务
了解应用中的微内核架构
【6月更文挑战第25天】**微内核架构**是将系统服务从内核移出,形成可选插件,增强扩展性和适应性。常见于第三方应用和嵌入式系统,如Linux、L4、WinCE。优点包括清晰结构、移植性和扩展性,但缺点是通信开销大、性能较低,不利于整体优化。适合需要灵活功能组合的场景。
443 5
了解应用中的微内核架构
|
消息中间件 运维 Prometheus
小红书消息中间件的运维实践与治理之路
近年来,消息领域的全面云原生化逐渐走向深入,比如 RocketMQ 5.0 版本的存算分离设计和 raft 模式,再比如 Kafka3.0 引入了分层设计的方式(tiered storage)和 raft 模式,以及近年来新崛起的 Pulsar 也开始采用云原生架构,在未来都可以针对具体业务需求引入进行功能迭代,发挥组件的最大价值。
1189 110
小红书消息中间件的运维实践与治理之路
|
存储 缓存 NoSQL
Redis从入门到精通之底层数据结构简单动态字符串(SDS)详解
SDS是Redis中的一种字符串类型,它是一种二进制安全的字符串,由简单动态字符串(SDS)实现。SDS支持多种数据结构,其中字符串(String)是最常用的一种数据结构之一。SDS的优点在于它可以避免C字符串常见的问题,比如缓冲区溢出和内存泄露等。SDS的常数复杂度获取字符串长度和杜绝缓冲区溢出可以避免使用strlen和strcat函数时的一些问题。同时,SDS的空间预分配和惰性空间释放两种策略可以减少修改字符串的内存重新分配次数。SDS也是二进制安全的,因为它不是以空字符串来判断字符串是否结束,而是以len属性表示的长度来判断字符串是否结束。SDS还兼容部分C字符串函数
920 86
Redis从入门到精通之底层数据结构简单动态字符串(SDS)详解
|
人工智能 开发者
黑神话:悟空中的AI行为树设计
【8月更文第26天】在《黑神话:悟空》这款游戏中,NPC(非玩家角色)的智能行为对于创造一个富有沉浸感的游戏世界至关重要。为了实现复杂的敌人行为模式,游戏开发团队采用了行为树作为NPC决策的核心架构。本文将详细介绍《黑神话:悟空》中NPC AI的设计原理,特别关注行为树的设计与实现。
700 0
|
网络协议 数据安全/隐私保护 网络架构
深入理解OSI模型及其层次结构
【8月更文挑战第24天】
628 0
|
运维 负载均衡 监控
服务网格下的东西向与南北向流量管理实践|学习笔记
快速学习服务网格下的东西向与南北向流量管理实践
1735 0
服务网格下的东西向与南北向流量管理实践|学习笔记