TCP ---滑动窗口以及拥塞窗口
序言
在上一篇文章中我们介绍了 TCP 中的协议段格式,以及保证其可靠传输的重传机制,着重介绍了三次握手建立连接,四次挥手断开连接的过程(👉点击查看)。
这只是 TCP 保证通信可信策略的一部分,现在让我们继续深入吧!
流量控制
1. 流量控制的目的
一个报文千辛万苦现在到达了目的主机,但是目的主机的缓冲区已经满了,那只有对不起了,只能把你丢弃了!对于 TCP 协议来说,我的报文已经发送了但是迟迟不见回应,那是不是丢了呀?我再发!另一方说,实在没位置了,你发一个我只有丢一个!网络资源就这样白白的浪费了,这种情况应该避免!
知道了问题,我们就应该思考问题的本质,为什么会这样?怎样避免?归根到底就是 发送方不知道接收方的接受能力导致的!如果发送方能知道接收方的接受能力从而按照对方的实际接受能力发送的话就不会出现这种问题! 这就是流量控制的目的。
2. 滑动窗口
在 TCP 协议段中有一个字段叫做 16位窗口大小,这就是在告诉对方我现在的可以接受的空间是多少,但是只有这个显然是不够的。咋们首先看一下滑动窗口到底是什么:
好了,本来对滑动窗口不熟悉的我,看了这幅图就更懵了😥!
首先我们需要理解 滑动窗口的窗口中维护的是需要发送的数据,因为窗口大小是和对方的接受能力相关的! 现在我想要提一个问题,比如我现在发送了 22 这个报文,那么我还得需要维护 22 嘛,还是窗口向右滑动呢?答案是,还需要维护 22 ,只有收到了相应的应答报文才可以向右滑动。
起始从简单理解的话,滑动窗口无非就是两个指针的移动,为了更好地理解,咋们来模拟一遍滑动的过程:
- 左指针为 22(代表窗口左边界),窗口大小为 8 字节,右指针为 29 (代表窗口右边界),现在将窗口的所有值发送
- 收到 22 的应答报文,返回的确认序号为 23, 代表下一次的起始,返回的窗口大小为 7。现在左指针指向 23,右指针指向 29
- 直接收到 26 的应答报文,返回的确认序号 27,下一次的开始,返回的窗口大小为 3。现在左指针指向 27,右指针指向 29。(💡
知识回顾:为什么收到 26 的应答报文就直接更新了呢,前面的 23,24,25不管了吗?这是因为应答报文的定义,收到该应答报文,就代表着该报文之前的数据也已经收到!
) - 收到 28 的应答报文,返回确认序号29,下一次的开始,返回的窗口大小为 5。现在左指针指向 29,右指针指向 33。将新加入窗口的数据发送(30 - 33)!
上述没有发生丢包的异常情况,如果有也别担心,会触发重传机制(快重传 or 超时重传
)。
3. 窗口关闭问题
滑动窗口实现了发送方按需发送的能力,但是还有一个问题。有没有可能出现接收方接收数据后,应用层处理数据的速度太慢了导致缓冲区数据满了,造成窗口大小最后返回 0 ,也就是窗口关闭的问题?
对于这个问题,接收方和发送方都有一定的策略:
- 对于接收方:TCP 为每个连接设有一个持续定时器,只要 TCP 连接一方收到对方的零窗口通知,就启动持续计时器。如果持续计时器超时,就会发送 窗口探测(Window probe)报文,而对方在确认这个探测报文时,给出自己现在的接收窗口大小。当然,如果多次探测之后窗口的大小还是 0 的话,就会发送
RST
中断连接。 - 对于接收方:处理完数据后窗口自然而然增大了,于是会向接收方发送窗口大小。
拥塞控制
1. 拥塞控制的目的
有了滑动窗口就极大避免了发送接收能力不对等的问题,但是正常的发送接收数据还和网络的状态有极大的状态。就比如早上四五点的网络状态肯定是比起晚上七八点要好很多的。当网络拥塞时,我们发送的数据包极有可能产生时延以及丢包问题,这会导致我们再次重发,加剧网络拥塞的状态。
拥塞的问题产生的原因就是网络上的数据包太多了,负担太大了。TCP 为了避免这种情况,使用了 拥塞窗口。
2. 慢启动
了解该算法之前,我们首先得知道拥塞窗口是什么:
- 发送开始的时候,定义拥塞窗口大小为 1
- 每次收到一个 ACK 应答, 拥塞窗口加 1
- 每次发送数据包的时候,
将拥塞窗口和接收端主机反馈的窗口大小做比较, 取较 小的值作为实际发送的窗口
现在了解了拥塞窗口,我们就可以了解慢启动算法的具体过程了:
- 发生拥塞时,拥塞窗口的值变为 1 ,并且呈指数级别增长
- 当到达一个门限时,由指数增长变为线性增长
- 再次发生拥塞时,拥塞窗口变为 1 ,并且更新门限(
新的门限 = 发生拥塞时的窗口大小 / 2
) - 重复 1- 3 的过程
了解了大概的过程,我们肯定心里也已经有了疑惑:
- 为什么要将窗口变为 1?并且采用指数增长?
- 为什么又要采用线性增长?
- 门限窗口的更新为什么是 发生拥塞时的窗口大小 / 2?
问题一:
发生拥塞时,在网络上的负担已经很重了,我们刚开始发送少数量的数据先让网络上的数据疏通之后,在慢慢增加发送数据的量恢复正常的通信速度。慢启动只是 刚开始发送的数据少,但是数据增加的速度可一点也不慢!
问题二:
如果一直采用指数增长的模式,那发送的数据量就会非常大,不出意外会快速的造成下一次拥塞的发生!所以替换为指数增长。有人肯定会想不增长行吗?一直维护在一个不会发生拥塞的大小。
网络的情况是一直在变化的 ! 正是因为如此,才需要不断地增长去探测网络的承受能力。就比如七八点网络高峰期,拥塞发生的频繁,现在大家都维持在一个恰当的窗口大小来避免拥塞的发生。但是,可能过了七八点到了凌晨的时候,网络情况大大的缓和了,但是我们的并没有继续线性探测来试探网络状态,你还是以那个值作为窗口大小不就是浪费你的传输速率吗?
问题三:
在这里的介绍慢启动的很多,解释明白了的很少。在这里我尝试用自己的理解来解释一下:网络是变化的,每一次发生拥塞时的窗口值都可能不一样,但是前后相邻两次的差距可能不会很大,所以当指数增长到上一次发生拥塞的值的一半时,就不要指数增长了,不然很可能再次拥塞,让用户的网速像过山车一样,一上一下一上一下。所以采取线性增长,不断地试探新的拥塞触发点,还可以让用户的网络情况尽量平稳一些。
面向字节流
1. 什么是面向字节流
我们在前面一直在提到 TCP 面向字节流,UDP 是面向数据报。那么到底是什么个意思呢?
首先我们先了解 面向数据报,当我们使用 UDP 发送数据时,该数据在传输层只会加一个报头然后交给下一层处理,对方在 UDP 所读取的也是一个完整的报文然后交付给上一层。总而言之,一个报文就是一次完整的发送数据。
TCP 是有一个真正意义上的缓冲区的,当我们需要发送数据时,会先将数据暂存在缓冲区,至于多久发送取决 发送窗口、拥塞窗口以及当前发送缓冲区的大小等条件。
就比如我想要发送两条信息:Nihao!
and How is going?
在底层的发送顺序可能是:
Nihao
|How is going?
Nihao How is gong?
Ni
|hao How is gong?
所以,我们不能简单认为 一个信息对应一个报文
。面向字节流和面向数据报之间最大的区别就是 报文和报文之间有没有明确的边界。
2. 粘包问题
因为 TCP 是面向字节流的,所以不可避免的报文和报文之间没有明显地边界,那该怎么办呢?TCP 并不负责这个,所以需要我们在应用层来处理。
1. 定长消息
我们约定好我们一次传输报文的大小是多少字节,然后只有接收方每次接收到指定字节大小数据,那么就认为读取到了一次完整的报文!但是这种方法不灵活。
2. 分隔符协议
发送方在每个数据包的结尾添加一个特定的分隔符,接收方根据此分隔符进行拆包操作。
还有许多方法在这里就不介绍了。
总结
这篇文章中,我们主要介绍了使用滑动窗口来控制流量,拥塞窗口解决拥塞问题,最后介绍了面向字节流,希望大家有所收获!
相关文章:

TCP ---滑动窗口以及拥塞窗口
序言 在上一篇文章中我们介绍了 TCP 中的协议段格式,以及保证其可靠传输的重传机制,着重介绍了三次握手建立连接,四次挥手断开连接的过程(👉点击查看)。 这只是 TCP 保证通信可信策略的一部分,现在让我们继续深入吧&…...

第十二章--- fixed 和 setprecision 函数、round 函数、进制转换及底层逻辑
1. 保留几位小数 在C中,如果你想要控制输出的小数点后的位数,可以使用<iomanip>头文件提供的fixed和setprecision函数。这里的fixed用于设置浮点数的输出格式为定点表示法,而setprecision(n)则用来指定小数点后保留的位数。具体用法如…...

ASP.NetCore---I18n(internationalization)多语言版本的应用
文章目录 0.实现的效果如下1.创建新项目I18nBaseDemo2.添加页面中的下拉框3.在HomeController中添加ChangeLanguage方法4.在Progress.cs 文件中添加如下代码:5. 在progress.cs中添加code6.添加Resource资源文件7.在页面中引用i18n的变量8. 重启项目,应该…...

vue3 环境配置vue-i8n国际化
一.依赖和插件的安装 主要是vue-i18n和 vscode的自动化插件i18n Ally https://vue-i18n.intlify.dev/ npm install vue-i18n10 pnpm add vue-i18n10 yarn add vue-i18n10 vscode在应用商城中搜索i18n Ally:如图 二.实操 安装完以后在对应项目中的跟package.jso…...

2024 uniapp入门教程 01:含有vue3基础 我的第一个uniapp页面
uni-app官网uni-app,uniCloud,serverless,快速体验,看视频,10分钟了解uni-app,为什么要选择uni-app?,功能框架图,一套代码,运行到多个平台https://uniapp.dcloud.net.cn/ 准备工作:HBuilder X 软件 HBuilder X 官网下载…...

CentOS 7文件系统
从centos7开始,默认的文件系统从ext4变成了XFS。随着虚拟化的应用越来越广泛,作为虚拟化磁盘来源的大文件(单个文件几GB级别)越来越常见。 1.XFS组成部分: XFS文件系统在数据的分布上主要划分为三部分:数据…...

vue源码解析(源码解析学习大纲)
文章目录 Vue源码解析入手方向大纲1.核心概念1-1.响应式系统1-2. 组件1-3. 虚拟DOM1-4. 指令1-5. 生命周期钩子 2.虚拟DOM2-1. 概念2-2. 工作流程2-3. 示例2-4.总结 3.组件系统3-1. 组件的定义3-2. 组件的创建3-3. 组件的模板3-4. 生命周期3-5. 事件处理3-6. 插槽(S…...

工行企业网银U盾展期后有两个证书问题的解决方法
工行企业网银U盾证书快到期后,可以自助展期,流程可以根据企业网银提示页面操作。操作后,可能存在两个新旧两个证书并存的情况,致使网银转账等操作失败,如图: 其原因是新证书生成后,旧证书没有删…...

《Linux从小白到高手》理论篇:文件权限控制及文件操作相关的命令
List item 本篇介绍Linux文件权限控制及文件操作相关的命令,看完本文,有关Linux文件权限控制及文件操作相关的常用命令你就掌握了99%了。 文件权限 在介绍文件权限之前先来复习下Linux的文件类型,始终记住那句话:Linux系统下&a…...

前端框架React的详细的学习方法和过程
学习React作为前端架构的一部分,是一个系统且逐步深入的过程。以下是一个详细的学习方法和过程,可以帮助你有效地掌握React: 1. 理解React的基础知识 首先,你需要了解React的基本概念,包括它是什么、为什么使用它以及…...

linux中缓存,在kafka上应用总结
linux中的缓存 页缓存 pagecatch(读缓存用于提供快速读)块缓存(用于提供其他设备快速写)当对读缓存读的时候,修改了读的数据,页缓存就会被标记为脏数据,等到写的时候它会向块缓存同步数据&…...

前端练习小项目 —— 让图片变得更 “色”
前言:相信读者在学习完了HTML、CSS和JavaScript之后已经想要迫不及待的想找一个小型的项目来练练手,那么这篇文章就正好能满足你的 “需求”。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客 在开始学习…...

时间卷积网络(TCN)原理+代码详解
目录 一、TCN原理1.1 因果卷积(Causal Convolution)1.2 扩张卷积(Dilated Convolution) 二、代码实现2.1 Chomp1d 模块2.2 TemporalBlock 模块2.3 TemporalConvNet 模块2.4 完整代码示例 参考文献 在理解 TCN 的原理之前ÿ…...

零散的知识
1.物化 在SQL中,物化(Materialization)是指将查询结果保存为物理数据结构以供后续使用的过程。这与普通的视图或查询不同,物化视图会存储查询的结果,而不是每次查询时都动态地重新计算数据。 ①物化视图 物化视图是一…...

Python读取pdf中的文字与表格
一、PyPDF2包安装 在Python中安装PyPDF2库,您可以使用pip包管理器。打开您的命令行工具(例如CMD、Terminal或Anaconda Prompt),然后输入以下命令: pip install PyPDF2 如果您使用的是Python 3,并且系统中…...

【MySQL 08】复合查询
目录 1.准备工作 2.多表查询 笛卡尔积 多表查询案例 3. 自连接 4.子查询 1.单行子查询 2.多行子查询 3.多列子查询 4.在from子句中使用子查询 5.合并查询 1.union 2.union all 1.准备工作 如下三个表,将作为示例,理解复合查询 EMP员工表…...

求1000以内的完数
题目:一个数如果恰好等于他的因子之和(包括1,但不包括这个数),这个数就是完数。编写算法找出1000之内的所有完数,并按下面格式输出其因子:28 its factors are 1,2,4,7,14 代码如下:…...

sqli-labs less-16 post提交dnslog注入
post提交DNSlog注入 第十六关和和十五关大差不大,可以使用布尔注入,时间盲注等,只不过闭合方式不一样,但是用布尔和时间盲太过于消耗时间,本次测试我将使用dnslog注入。 使用在线平台http://www.dnslog.cn/ 闭合方式…...

nginx报错|xquic|xqc_engine_create: fail|
一.问题描述 nginx使用xquic协议一切安装正常,nginx -s reload也正常,但就是访问不了网页 [emerg] 12342#0: |xquic|xqc_engine_create: fail| [emerg] 12342#0: |xquic|ngx_xquic_process_init|engine_init fail| [emerg] 12341#0: |xquic|xqc_engine_create: fai…...

Java虚拟机(JVM)
目录 内存区域划分堆(Heap)方法区(Method Area)程序计数器(Program Counter Register)虚拟机栈(VM Stack)本地方法栈(Native Method Stack) 类加载的过程类加…...

MQ 架构设计原理与消息中间件详解(三)
RabbitMQ实战解决方案 RabbitMQ死信队列 死信队列产生的背景 RabbitMQ死信队列俗称,备胎队列;消息中间件因为某种原因拒收该消息后,可以转移到死信队列中存放,死信队列也可以有交换机和路由key等。 产生死信队列的原因 消息投…...

大数据新视界 --大数据大厂之 Alluxio 数据缓存系统在大数据中的应用与配置
💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

PHP基本语法总结
目录 输出语句 注释 数据类型(变量) 局部和全局作用域 类型比较(松散比较与严格比较) 常量 运算符 并置运算符 不等于 逻辑运算符 条件语句 数组 关联数组 数组排序 一般数组 关联数组 循环 函数 变量函数 魔…...

尚硅谷rabbitmq 2024第30-33节 死信队列 答疑
Virtual host: Type: Name: Durabiity: Arguments: Default for virtual host w ququt.normal.video Durable x-dead-letter-exchange x-dead-1etter-routing-xey x-mAx-1ength X-m在88点0也-6E1 exchange.dead.letter.vide zouting.key.dead.ietter.v 10 String String Number…...

解锁空间距离计算的多种方式-含前端、空间数据库、后端
目录 前言 一、空间数据库求解 1、PostGIS实现 二、GIS前端组件求解 1、Leaflet.js距离测算 2、Turf.js前端计算 三、后台距离计算生成 1、欧式距离 2、Haversice球面距离 3、GeoTools距离计算 4、Gdal距离生成 5、geodesy距离计算 四、成果与生成对比 1、Java不…...

Windows 开发工具使用技巧 QT使用安装和使用技巧 QT快捷键
一、QT配置 1. 安装 Qt 开发框架 1、下载 1、进入下载地址 下载地址1 (官方, 需注册账号): https://www.qt.io/download下载地址2(推荐): http://download.qt.io/http://download.qt.io/archive/qt/ (或更直接的…...

【实战教程】SpringBoot全面指南:快速上手到项目实战(SpringBoot)
文章目录 【实战教程】SpringBoot全面指南:快速上手到项目实战(SpringBoot)1. SpringBoot介绍1.1 SpringBoot简介1.2系统要求1.3 SpringBoot和SpringMVC区别1.4 SpringBoot和SpringCloud区别 2.快速入门3. Web开发3.1 静态资源访问3.2 渲染Web页面3.3 YML与Properti…...

LeetCode讲解篇之1043. 分隔数组以得到最大和
文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 对于这题我们这么考虑,我们选择以数字的第i个元素做为分隔子数组的右边界,我们需要计算当前分隔子数组的长度为多少时能让数组[0, i]进行分隔数组的和最大 我们用数组f表示[0, i)区间内的…...

Python知识点:结合Python工具,如何使用TfidfVectorizer进行文本特征提取
开篇,先说一个好消息,截止到2025年1月1日前,翻到文末找到我,赠送定制版的开题报告和任务书,先到先得!过期不候! 如何使用Python的TfidfVectorizer进行文本特征提取 在自然语言处理(…...

Diffusion models(扩散模型) 是怎么工作的
前言 给一个提示词, Midjourney, Stable Diffusion 和 DALL-E 可以生成很好看的图片,那么它们是怎么工作的呢?它们都用了 Diffusion models(扩散模型) 这项技术。 Diffusion models 正在成为生命科学等领域的一项尖端技术&…...