【TCP】滑动窗口、流量控制 以及拥塞控制
滑动窗口、流量控制 以及拥塞控制
- 1. 滑动窗口(效率机制)
- 2. 流量控制(安全机制)
- 3. 拥塞控制(安全机制)
1. 滑动窗口(效率机制)
TCP 使用 确认应答 策略,对每一个发送的数据段,都要给一个 ACK 确认应答。收到 ACK 后再发送下一个数据段。这样做有一个比较大的缺点,就是性能较差。尤其是数据往返的时间较长的时候。

既然这样一发一收的方式性能较低,那么我们一次发送多条数据,使用滑动窗口,就可以大大的提高性能(其实是将多个段的等待时间重叠在一起了)。
滑动窗口存在的意义就是在保证可靠性的前提下,尽量提高效率。

- 窗口大小指的是无需等待确认应答而可以继续发送数据的最大值。上图的窗口大小就是 4000 个字节(四个段)。
- 发送前四个段的时候,不需要等待任何 ACK,直接发送;
- 收到第一个 ACK 后,滑动窗口向后移动,继续发送第五个段的数据;依次类推;
(相当于一份等待时间等待多份 ACK, 当然不能不等,可靠传输的灵魂就是确认应答, 若没有 ACK,可靠传输就形同虚设。) - 操作系统内核为了维护这个滑动窗口,需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答;只有确认应答过的数据,才能从缓冲区删掉;
- 在一定范围内,窗口越大,传输速率就越快,网络的吞吐率就越高

那么如果出现了丢包,如何进行重传?这里分两种情况讨论。
- 情况一:数据包已经抵达,ACK 被丢了。

这种情况下,部分 ACK 丢了并不要紧,因为可以通过后续的ACK进行确认.
ACK 的确认号有特定含义,保证后一条 ACK 覆盖前一条,
比如并没有收到 1001 ACK, 但是收到了 2001 ACK 就说明 2001 之前的数据全部已经收到了。
若发送 4001 ~ 5000 之前,只收到了 4001, 但是它的意思是,4001 之前的都收到了,窗口就可以一次往下挪动 4 个。
- 情况二:数据包就直接丢了。

- 当某一段报文段丢失之后,发送端会一直收到 1001 这样的 ACK,就像是在提醒发送端 “我想要的是 1001” 一样;
- 如果发送端主机连续三次收到了同样一个 “1001” 这样的应答,就会将对应的数据 1001 - 2000 重新发送;
- 这个时候接收端收到了 1001 之后,再次返回的 ACK 就是 7001 了(因为2001 - 7000)接收端其实之前就已经收到了,被放到了接收端操作系统内核的接收缓冲区中;
(重传只需要把丢的数据重传就行了,后面已经传过的数据不用再传了。)
这种机制被称为 “高速重发控制”(也叫 “快重传”)。
(为什么说是 “快” 重传,因为可能收到三个连续相同的 ACK 的时间内还没有触发超时机制,也就是还没超时呢,但是不等触发超时,直接就重传了。)
2. 流量控制(安全机制)
流量控制是滑动窗口的延伸,目的是为了保证可靠性。
- 在一定范围内,滑动窗口越大传输效率就越高,但是不能只考虑发送方,不考虑接收方,
- 接收端处理数据的速度是有限的。如果发送端发的太快,导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应。
因此 TCP 支持根据接收端的处理能力,来决定发送端的发送速度。这个机制就叫做流量控制(Flow Control);
- 接收端将自己可以接收的缓冲区大小放入 TCP 首部中的 “窗口大小” 字段,通过 ACK 端通知发送端;
- 发送方接收到这个这个数据后,就会灵活的调整发送速度,调整窗口大小
- 窗口大小字段越大,说明网络的吞吐量越高;
- 接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端;
- 发送端接受到这个窗口之后,就会减慢自己的发送速度;
- 如果接收端缓冲区满了,就会将窗口置为 0;
- 这时发送方不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端。

-
接收端如何把窗口大小告诉发送端呢?
回忆我们的 TCP 首部中,有一个16 位窗口字段,就是存放了窗口大小信息; -
那么问题来了,16 位数字最大表示 65535,那么 TCP 窗口最大就是 65535 字节么?
实际上,TCP 首部40字节选项中还包含了一个窗口扩大因子 M,实际窗口大小是 窗口字段的值左移 M 位即 65535 * 2 ^M
3. 拥塞控制(安全机制)
拥塞控制,也是滑动窗口的延伸,限制滑动窗口的发送速率。
拥塞控制描述的是发送方到接收方整个链路直接的拥堵情况。
- 最终的滑动窗口的大小 = Min (流量控制窗口,拥塞控制窗口)
虽然TCP有了滑动窗口这个大杀器,能够高效可靠的发送大量的数据。
但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题。
因为网络上有很多的计算机,可能当前的网络状态就已经比较拥堵。在不清楚当前网络状态下,贸然发送大量的数据,是很有可能引起雪上加霜的。
- 发送方开始时以一个较小的窗口来发送数据,
- 若数据很流畅到达,就逐渐加大窗口大小,
- 若加大到一定程度出现丢包,就减小窗口,
- 通过反复的增大/减小过程,逐渐找到一个合适的范围,拥塞窗口就在这个范围中不断变化,达到一个 “动态平衡”。
具体拥塞窗口是怎么变化的呢 ?

- 慢开始
初始值 窗口大小为 1, 然后以指数级别增长,“慢开始” 只是指初使时慢,但是增长速度非常快。 - 拥塞避免
窗口值到达 ssthresh 时,从指数增长变为 线性增长。 - 网络拥塞
出现大量丢包情况,说明网络拥塞了,拥塞窗口大小直接变为 1 。ssthresh 阈值变为此时拥塞窗口大小的一半,图中就是从 变为 24 的一半 12 。
(少量的丢包,我们仅仅是触发超时重传;大量的丢包,我们就认为网络拥塞;) - 然后重新慢开始,循环这个过程。
当TCP通信开始后,网络吞吐量会逐渐上升;随着网络发生拥堵,吞吐量会立刻下降;
-
为什么使用指数级别的增长速度 ?
因为希望能快速接近 ssthresh 阈值, 既希望速度快,又希望不大量丢包,如果初始情况给的窗口大小很小,可能合适的值是个很大的值,那么使用指数增长的话,能够很快的接近这个值。 -
ssthresh 的意义 ?
决定了什么时候从指数增长变为线性增长 -
拥塞窗口最理想的大小 ?
ssthresh 值与 出现拥塞的这个值之间是最理想的效果,这个范围之间传输速率较快,并且没有大量丢包。 -
为什么出现拥塞时,直接让窗口变为初始值 1 ?
因为网络的情况很复杂,不稳定,如果出现大量丢包,很可能速度降下来一点是不能解决问题的,速度降得太慢还会有可能出现持续丢包,就会对网络质量带来很大影响,一下让窗口变得很小,就是期望这次传输一定能成功。
拥塞控制,归根结底是TCP协议想尽可能快的把数据传输给对方,但是又要避免给网络造成太大压力的折中方案。
常见面试题:
- UDP 本身是无连接,不可靠,面向数据报的协议,如果要基于传输层UDP协议,来实现一个可靠传输,应该如何设计?
- UDP 大小是受限的,如果要基于传输层UDP协议,传输超过64K的数据,应该如何设计?
以上两个问题答案类似,都可以参考TCP的可靠性机制然后在应用层实现类似的逻辑:
如:
- 引入序列号,保证数据顺序;
- 引入确认应答,确保对端收到了数据,保证可靠传输;
- 引入超时重传,如果隔一段时间没有应答,就重发数据;
- 引入滑动窗口;
- 引入窗口扩大选项;
- 引入流量控制
- 引入拥塞控制
- ……
好啦! 以上就是对 TCP 滑动窗口、流量控制 以及拥塞控制的讲解,希望能帮到你 !
评论区欢迎指正 !
相关文章:
【TCP】滑动窗口、流量控制 以及拥塞控制
滑动窗口、流量控制 以及拥塞控制 1. 滑动窗口(效率机制)2. 流量控制(安全机制)3. 拥塞控制(安全机制) 1. 滑动窗口(效率机制) TCP 使用 确认应答 策略,对每一个发送的数…...
Xilinx FPGA管脚约束语法规则(UCF和XDC文件)
文章目录 1. ISE环境(UCF文件)2. Vivado环境(XDC文件) 本文介绍ISE和Vivado管脚约束的语句使用,仅仅是管脚和电平状态指定,不包括时钟约束等其他语法。 ISE使用UCF文件格式,Vivado使用XDC文件&…...
服务网格和CI/CD集成:讨论服务网格在持续集成和持续交付中的应用。
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...
代码随想录训练营第56天|583.两个字符串的删除操作,72.编辑距离
代码随想录训练营第56天|583.两个字符串的删除操作,72.编辑距离 583.两个字符串的删除操作文章思路代码 72.编辑距离文章思路代码 总结 583.两个字符串的删除操作 文章 代码随想录|0583.两个字符串的删除操作 思路 如果不按照编辑距离考虑的话,只需要…...
【JDK 8-Lambda】3.1 Java高级核心玩转 JDK8 Lambda 表达式
一、 什么是函数式编程 ? 二、 什么是lambda表达式? 1. 先看两个示例 A.【创建线程】 B.【数组排序-降序】 2. lambda表达式特性 A. 使用场景(前提): B. 语法 (params) -> expression C. 参数列表 D. 方法体 F. 好处 一、 什么是函数式编…...
【C#】XML的基础知识以及读取XML文件
最近在学读取文件 目录 介绍特点结构XML的语法规则XML 命名规则 C#操作XML新建读取第一种第二种第三种 读取属性 介绍 XML (可扩展标记语言,eXtensible Markup Language) 是一种标记语言,它被设计用来传输和存储数据。 特点 可扩展性:由于…...
Immutable.js简介
引子 看一段大家熟悉的代码 const state {str: wwming,obj: {y: 1},arr: [1, 2, 3] } const newState stateconsole.log(newState state) // truenewState和state是相等的 原因: 由于js的对象和数组都是引用类型。所以newState的state实际上是指向于同一块内存…...
C语言进阶教程(位操作和进制数的表示)
文章目录 前言一、左移和右移二、清除对应的位为0和设置对应的位为11.设置对应的位为12.清除对应的位为0 三、进制数的表示四、& ^ | ~总结 前言 本篇文章给大家讲解一下C语言中的位操作,在嵌入式中位操作是经常需要使用的,那么下面就让我们来学习一…...
Loguru:功能强大、简单易用的Python日志库
文章目录 Loguru:Python的日志库安装 Loguru基本用法配置 Loguruadd() 语句remove() 语句设置日志文件保留日志的等级设置控制台日志显示等级Loguru:Python的日志库 Loguru 是一个功能强大、简单易用的日志库,可以让 Python 的日志记录变得更加轻松。它提供了丰富的功能和配…...
idea之maven的安装与配置
我们到maven的官网里下载maven,地址:https://maven.apache.org/download.cgi下载完成后解压即可配置环境变量 此电脑–>右键–>属性–>高级系统设置–>环境变量–>系统变量(S)–>新建一个系统变量 变量名&…...
【最新面试问题记录持续更新,java,kotlin,android,flutter】
最近找工作,复习了下java相关的知识。发现已经对很多概念模糊了。记录一下。部分是往年面试题重新整理,部分是自己面试遇到的问题。持续更新中~ 目录 java相关1. 面向对象设计原则2. 面向对象的特征是什么3. 重载和重写4. 基本数据类型5. 装箱和拆箱6. …...
面试:经典问题解决思路
1. 秒杀系统架构 参考:秒杀系统架构优化思路 2. 如何防止订单重复提交 重复提交原因: 一种是由于用户在短时间内多次点击下单按钮,或浏览器刷新按钮导致。另一种则是由于Nginx或类似于SpringCloud Gateway的网关层,进行超时重试造成的。 方案…...
CG MAGIC分享3ds Max卡顿未保存处理方法有哪些?
3ds Max进行建模、渲染这一系列过程中,大家使用中都会遇到各种原因导致软件卡顿或崩溃是很常见的情况。 可以说卡机没关系,可是卡顿发生时,如果之前的工作没有及时保存,可能会导致数据的丢失和时间的浪费。这就是最让人烦躁的了&…...
[python 刷题] 238 Product of Array Except Self
[python 刷题] 238 Product of Array Except Self 题目: Given an integer array nums, return an array answer such that answer[i] is equal to the product of all the elements of nums except nums[i]. The product of any prefix or suffix of nums is guar…...
UG NX二次开发(C#)-计算直线到各个坐标系轴向的投影角度
文章目录 1、前言2、需求分析3、NXOpen方法实现3.1 创建基准坐标系3.2 然后计算直线到基准坐标系的轴向角度3.3 代码调用4、测试效果为:1、前言 最近有个粉丝问我如何计算直线到坐标系各个轴向的角度,这里用UG NX二次开发(C#)实现。当然,这里的内容是经验之谈,如果有更好的…...
C# ComboBox 和 枚举类型(Enum)相互关联
C# ComboBox 和 枚举类型(Enum)相互关联 目的 在C# Winform面板上的ComboBox选择项,由程序填写某个Enum的各个枚举项目。 在运行中读取ComboBox的选择项,返回Enum数值。 非编程方法 低阶做法可以在winform设计窗口手动填写,但是不会自动跟…...
Linux CentOS7 tree命令
tree就是树,是文件或文件名输出到控制台的一种显示形式。 tree命令作用:以树状图列出目录的内容,包括文件、子目录及子目录中的文件和目录等。 我们使用ll命令显示只能显示一个层级的普通文件和目录的名称。而使用tree则可以树的形式将指定…...
软件设计模式系列之九——桥接模式
1 模式的定义 桥接模式是一种结构型设计模式,它用于将抽象部分与其实现部分分离,以便它们可以独立地变化。这种模式涉及一个接口,它充当一个桥,使得具体类可以在不影响客户端代码的情况下改变。桥接模式将继承关系转化为组合关系…...
构造函数的调用规则
#include <iostream> #include <string> using namespace std; class person{ public:int m_age; // person(){ // cout<<"默认构造的调用"<<endl; // } // person(int age){ // m_ageage; // cout<<"有参构造的调用"<…...
第十章:枚举类与注解
10.1:枚举类的使用 当需要定义一组常量时,建议使用枚举类(前提:类的对象只有有限个,确定的) eg: 星期:Mondey、.....、Sunday 性别:Man、.....、Woman 线程状态ÿ…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
