TCP ---滑动窗口以及拥塞窗口

news2024/10/4 20:42:39

序言

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


流量控制

1. 流量控制的目的

 一个报文千辛万苦现在到达了目的主机,但是目的主机的缓冲区已经满了,那只有对不起了,只能把你丢弃了!对于 TCP 协议来说,我的报文已经发送了但是迟迟不见回应,那是不是丢了呀?我再发!另一方说,实在没位置了,你发一个我只有丢一个!网络资源就这样白白的浪费了,这种情况应该避免!
 知道了问题,我们就应该思考问题的本质,为什么会这样?怎样避免?归根到底就是 发送方不知道接收方的接受能力导致的!如果发送方能知道接收方的接受能力从而按照对方的实际接受能力发送的话就不会出现这种问题! 这就是流量控制的目的。

2. 滑动窗口

 在 TCP 协议段中有一个字段叫做 16位窗口大小,这就是在告诉对方我现在的可以接受的空间是多少,但是只有这个显然是不够的。咋们首先看一下滑动窗口到底是什么:
在这里插入图片描述
好了,本来对滑动窗口不熟悉的我,看了这幅图就更懵了😥!

 首先我们需要理解 滑动窗口的窗口中维护的是需要发送的数据,因为窗口大小是和对方的接受能力相关的! 现在我想要提一个问题,比如我现在发送了 22 这个报文,那么我还得需要维护 22 嘛,还是窗口向右滑动呢?答案是,还需要维护 22 ,只有收到了相应的应答报文才可以向右滑动。

 起始从简单理解的话,滑动窗口无非就是两个指针的移动,为了更好地理解,咋们来模拟一遍滑动的过程:

  1. 左指针为 22(代表窗口左边界),窗口大小为 8 字节,右指针为 29 (代表窗口右边界),现在将窗口的所有值发送
  2. 收到 22 的应答报文,返回的确认序号为 23, 代表下一次的起始,返回的窗口大小为 7。现在左指针指向 23,右指针指向 29
  3. 直接收到 26 的应答报文,返回的确认序号 27,下一次的开始,返回的窗口大小为 3。现在左指针指向 27,右指针指向 29。(💡知识回顾:为什么收到 26 的应答报文就直接更新了呢,前面的 23,24,25不管了吗?这是因为应答报文的定义,收到该应答报文,就代表着该报文之前的数据也已经收到!
  4. 收到 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. 当到达一个门限时,由指数增长变为线性增长
  3. 再次发生拥塞时,拥塞窗口变为 1 ,并且更新门限(新的门限 = 发生拥塞时的窗口大小 / 2
  4. 重复 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. 分隔符协议

 发送方在每个数据包的结尾添加一个特定的分隔符,接收方根据此分隔符进行拆包操作。

还有许多方法在这里就不介绍了。


总结

 这篇文章中,我们主要介绍了使用滑动窗口来控制流量,拥塞窗口解决拥塞问题,最后介绍了面向字节流,希望大家有所收获!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2188667.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

盲拍合约:让竞拍更公平与神秘的创新解决方案

目录 前言 一、盲拍合约是什么? 二、盲拍合约工作原理 1、合约创建与初始化 2、用户出价(Bid) 3、出价结束 4、披露出价(Reveal) 5、处理最高出价 6、结束拍卖 7、退款与提款 三、解析盲拍合约代码…

02:(寄存器开发)流水灯/按键控制LED

寄存器开发 1、LED流水灯2、按键控制LED 1、LED流水灯 通过第一章的学习,我们已然知晓了LED的点亮和熄灭的方式,下面学习流水灯的制作流程。 流水灯呈现的样子:就是第一个LED灯点亮,延迟一段时间,第一个LED灯熄灭第二…

2020大厂web前端面试常见问题总结

本篇收录了一些面试中经常会遇到的经典面试题以及自己面试过程中遇到的一些问题。通过对本篇知识的整理以及经验的总结,希望能帮到更多的前端面试者。 1.web前端项目的结构是怎样的?文件有哪些命名规范? 项目结构规范 页面文件:以…

树莓派5:换源(针对Debian12)+安装包管理器Archiconda(图文教程+详细+对初学者超级友好)

目录 一、安装官方发行版系统(Debian)二、换源(记得参考上述教程ssh连接到树莓派Terminal,or外接一块Hdmi显示屏)2.1 查看自己安装的树莓派镜像架构2.2 查询自己的系统版本2.3 打开清华大学开源软件镜像站网站2.3.1 传…

浅析Golang的Context

文章目录 1. 简介2. 常见用法2.1 控制goroutine的生命周期(cancel)2.2 传递超时(Timeout)信息2.3 传递截止时间(Deadline)2.4 传递请求范围内的全局数据 (value) 3 特点3.1 上下文的…

FWA(固定无线接入),CPE(客户终端设备)简介

文章目录 FWA(Fixed Wireless Access),固定无线接入CPE(Customer Premise Equipment),用户驻地设备 FWA(Fixed Wireless Access),固定无线接入 固定无线接入&#xff08…

Geogebra009—构建正六边形

继续巩固一下基础,本篇我们来做一个正六边形 目录 一、成品展示二、涉及内容三、做图步骤1. 绘制一个以A点为圆心过B点的圆circle1;2. 以B点为圆心过A点绘制另外一个圆circle2;3. 绘制两个圆的交点,得到顶点C和D;4. 以…

Leetcode: 0001-0010题速览

Leetcode: 0001-0010题速览 本文材料来自于LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer(第 2 版)》、《程序员面试金典(第 6 版)》题解 遵从开源协议为知识共享 版权归属-相同方式…

奔驰GLS450升级原厂电吸门效果怎么样

奔驰GLS450升级原厂电吸门后,能带来以下效果: • 关门更优雅:只需轻轻推车门到基本关闭的位置,当车门距离车门锁大约6毫米时,传感器便会启动电动马达将车门安静地拉入,然后固定住,告别传统关门…

HTML+CSS基础用法介绍五

目录: 结构伪类选择器盒子模型-边框线盒子模型-内边距盒子模型-解决盒子被撑大盒子模型-外边距与版心居中小知识:清除浏览器中所有标签的默认样式内容溢出控制显示方式盒子模型-圆角 🐎正片开始 结构伪类选择器 什么是结构伪类选择器&…

18.安卓逆向-frida基础-调试实战2

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于:图灵Python学院 本人写的内容纯属胡编乱造,全都是合成造假,仅仅只是为了娱乐,请不要盲目相信。 工…

Windows UAC权限详解以及因为权限不对等引发软件工具无法正常使用的实例分析

目录 ​1、什么是UAC? 2、微软为什么要设计UAC? 3、标准用户权限与管理员权限 4、程序到底以哪种权限运行?与哪些因素有关? 4.1、给程序设置以管理员权限运行的属性 4.2、当前登录用户的类型 4.3、如何通过代码判断某个进程…

智能 AI 写作软件:开启创作新纪元

不论你在哪行哪业应该都躲不开写作这件事被。写作已经成为了我们生活和工作中不可或缺的一部分。随着人工智能技术的飞速发展,AI 智能写作工具应运而生。接下来,让我们一起揭开智能ai写作工具的神秘面纱。 1.笔灵AI写作 直通车:https://ibi…

②EtherCAT转ModbusTCP, EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关

EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关https://item.taobao.com/item.htm?ftt&id822721028899 协议转换通信网关 EtherCAT 转 Modbus TCP (接上一章) GW系列型号 配置说明 上载 网线连接电脑到模块上的 WEB 网页设置网口&#…

论文笔记:Online Class-Incremental Continual Learning with Adversarial Shapley Value

这篇工作的focus 是 memory-based approach 1. 挑战/问题: 灾难性遗忘:深度神经网络在学习新任务时往往会忘记先前任务的知识。内存和计算效率:在个人设备上执行深度学习任务时,需要最小化内存占用和计算成本。数据流增量学习&am…

系统安全 - 大数据组件的安全及防护

文章目录 导图1. Hadoop的安全风险2. 常见攻击方式3. Hadoop的自带安全功能4. Apache Knox和Apache Ranger等安全框架5. 安全策略建议 导图 1. Hadoop的安全风险 Hadoop最初设计为在可信网络中运行,因此默认安全性较低。常见的安全风险包括: 未经授权的…

探索未来:揭秘pymqtt,AI与物联网的新桥梁

文章目录 探索未来:揭秘pymqtt,AI与物联网的新桥梁背景:为什么选择pymqtt?什么是pymqtt?如何安装pymqtt?简单的库函数使用方法1. 配置MQTT连接2. 创建Mqtt对象3. 发布消息4. 订阅主题5. 运行MQTT客户端 场景…

Java项目实战II基于Java+Spring Boot+MySQL的小徐影城管理系统设计与实现(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者 一、前言 随着文化娱乐产业的快速发展,影城管理面临着日益复杂的挑战,包括票务管理、座…

Redis操作常用API

说明&#xff1a;Redis应用于java项目中&#xff0c;操作Redis数据可以使用API&#xff0c;相较于命令行更方便。使用前&#xff0c;需先添加依赖。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-re…