5.4、TCP 流量控制(滑动窗口机制)

news2025/1/16 16:38:24

一般来说,我们总是希望数据传输得更快一些。

  • 但如果发送方把数据发送得过快,接收方就可能来不及接收,这就会造成数据的丢失。

所谓流量控制(flow control)就是 让发送方的发送速率不要太快,要让接收方来得及接收 \color{red}让发送方的发送速率不要太快,要让接收方来得及接收 让发送方的发送速率不要太快,要让接收方来得及接收

利用 滑动窗口 \color{red}滑动窗口 滑动窗口机制可以很方便地在 TCP 连接上实现对发送方的流量控制。

1、A、B建立TCP连接

假设主机 AB 是因特网上的两台主机

它们之间已经建立了 TCP 连接,AB 发送数据,BA 进行流量控制

image-20230104235028176

这是主机 A 中待发送数据的字节序号

image-20230104235135647

假设主机 A 发送的每个 TCP 数据报文段可携带 100 100 100 字节数据

  • 因此图中每个小格子表示 100 100 100 个字节数据的序号

在主机 AB 建立 TCP 连接时,B 告诉 A :“我的接收窗口为 400”

  • 因此,主机 A 将自己的发送窗口也设置为 400 400 400

这意味着主机 A 在未收到主机 B 发来的确认时,可将序号落入发送窗口中的全部数据发送出去

image-20230104235819989


2、A发送TCP报文段

主机A对B的流量控制

主机 A 将发送窗口内序号 1 1 1 ~ 100 100 100 的数据封装成一个 TCP 报文段发送出去

  • 发送窗口内还有 300 300 300 字节可以发送

这里的 seqTCP 报文段首部中的序号字段

  • 取值 1 1 1 表示 TCP 报文段数据载荷的第一个字节的序号是 1 1 1

这列的 data 表示这是 TCP 数据报文段

image-20230105000126424


主机 A 将发送窗口内序号 101 101 101 ~ 200 200 200 的数据封装成一个 TCP 报文段发送出去

  • 发送窗口内还有 200 200 200 字节可以发送

主机 A 将发送窗口内序号 201 201 201 ~ 300 300 300 的数据封装成一个 TCP 报文段发送出去

  • 但该报文段在传输过程中 丢失 \color{red}丢失 丢失

  • 发送窗口内还有 100 100 100 字节可以发送

image-20230105000320084


3、B对A的累计确认并进行第一次流控

主机 B 对主机 A 所发送的 201 201 201 号以前的数据进行 累计确认 \color{red}累计确认 累计确认

并在该累计确认中将窗口字段的值调整为 300 300 300 ,对主机 A 进行流控

这里的大写 ACKTCP 报文段首部中的 标志位 \color{blue}标志位 标志位

  • 取值 1 1 1 表示这是一个 TCP 确认报文段

小写 ackTCP 报文段首部中的 确认号字段 \color{blue}确认号字段 确认号字段

  • 取值 201 201 201 表示序号 201 201 201 之前的数据已全部正确接收

  • 现在希望收到序号 201 201 201 及其后续数据

rwndTCP 报文段首部中的 窗口字段 \color{blue}窗口字段 窗口字段

  • 取值 300 300 300 表示自己的接收窗口大小为 300 300 300

image-20230105000930866


4、A发送TCP报文段但丢失了

主机 A 收到该累计确认后,将发送窗口向前滑动

  • 使已发送并受到确认的这些数据的序号移出发送窗口

由于主机 B 在该累计确认中将自己的接收窗口调整为了 300 300 300

  • 因此,主机 A 相应的将自己的发送窗口调整为 300 300 300

目前,主机 A 发送窗口内的序号为 201 201 201 ~ 500 500 500

也就是主机 A 还可以发送这 300 300 300 字节

  • 其中 201 201 201 ~ 300 300 300 字节是已发送的数据
  • 若重传计时器超时,它们会被重传

image-20230105001644425

301 301 301 ~ 400 400 400 号字节以及 401 401 401 ~ 500 500 500 号字节还未被发送

  • 可被分别封装在一个 TCP 报文段中发送

主机 A 现在可将发送缓存中序号 1 1 1 ~ 200 200 200 的字节数据全部删除了

  • 因为已经收到了主机 B 对它们的累计确认

主机 A 将发送窗口内序号 301 301 301 ~ 400 400 400 的数据封装成一个 TCP 报文段发送出去

  • 发送窗口内还有 100 100 100 字节可以发送

主机 A 将发送窗口内序号 401 401 401 ~ 500 500 500 的数据封装成一个 TCP 报文段发送出去

  • 至此,序号落在发送窗口内的数据已经全部发送出去了, 不能发送新数据了 \color{red}不能发送新数据了 不能发送新数据了

image-20230105002331166


现在,发送窗口内序号 201 201 201 ~ 300 300 300 100 100 100 个字节数据的重传计时器超时了

主机 A 将他们重新封装成一个 TCP 报文段发送出去

tcpchongchuan.gif


5、B对A的累计确认并进行第二次流控

主机 B 收到该重传的 TCP 报文段后,对主机 A 所发送的 501 501 501 号以前的数据进行累计确认

  • 并在该累计确认中将窗口字段的值调整为 100 100 100

这是主机 B 对主机 A 进行的第二次流量控制

image-20230105003035588


主机 A 收到该累计确认后,将发送窗口向前滑动

  • 使已发送并受到确认的这些数据的序号移出发送窗口

由于主机 B 在该累计确认中将自己的接收窗口调整为了 100 100 100

  • 因此,主机 A 相应的将自己的发送窗口调整为 100 100 100

目前,主机 A 发送窗口内的序号为 501 501 501 ~ 600 600 600

也就是主机 A 还可以发送这 100 100 100 字节

image-20230105003220746

主机 A现在可将发送缓存中序号 201 201 201 ~ 500 500 500 的字节数据全部删除了

  • 因为已经收到了主机 B 对它们的累计确认

image-20230105003244176


6、A发送TCP报文段

主机 A 将发送窗口内序号 501 501 501 ~ 600 600 600 的数据封装成一个 TCP 报文段发送出去

  • 至此,序号落在发送窗口内的数据已经全部发送出去了, 不能发送新数据了 \color{red}不能发送新数据了 不能发送新数据了

tcpfasong501.gif

7、B对A的累计确认并进行第三次流控

主机 B 收到该重传的 TCP 报文段后,对主机 A 所发送的 601 601 601 号以前的数据进行累计确认

  • 并在该累计确认中将窗口字段的值调整为 0 0 0

这是主机 B 对主机 A 进行的第三次流量控制

image-20230105003636261


主机 A 收到该累计确认后,将发送窗口向前滑动

  • 使已发送并受到确认的这些数据的序号移出发送窗口

tcphuadong.gif

由于主机 B 在该累计确认中将自己的接收窗口调整为了 0 0 0

  • 因此,主机 A 相应的将自己的发送窗口调整为 0 0 0

tcptiaozheng.gif

目前主机 A 不能再发送一般的 TCP 报文段了

主机 A 现在可将发送缓存中序号 501 501 501 ~ 600 600 600 的字节数据全部删除了

  • 因为已经收到了主机 B 对它们的累计确认

image-20230105004138032


8、TCP 死锁问题

假设主机 B 向主机 A 发送了零窗口的报文段后不久,主机 B 的接收缓存又有了一些存储空间

  • 于是,主机 B 向主机 A 发送了接收窗口等于 300 300 300 的报文段

tcphuancun.gif

然而,这个报文段再传输过程中丢失了,主机 A 一直等待主机 B 发送的非零窗口的通知

  • 而主机 B 也一直等待 A 发送的数据

如果不采取措施,这种互相等待而形成的死锁局将一致持续下去

image-20230105004730090

为了解决这个问题,TCP 为每一个连接设置了一个 持续计时器 \color{red}持续计时器 持续计时器

  • 只要 TCP 连接的一方收到对方的零窗口通知,就启动持续计时器

若持续计时器超时,就发送一个 零窗口探测报文 \color{red}零窗口探测报文 零窗口探测报文,仅携带 1 1 1 字节的数据

而对方在确认这个探测报文段时,给出自己现在的接收窗口值

  • 若接收窗口仍然是 0 0 0,那么收到这个报文段的一方就重新启动持续计时器

  • 若接收窗口不是 0 0 0,那么死锁的局面就可以被打破了


在本例中,主机 A 收到零窗口通知时,就启动一个持续计时器

  • 当持续计时器超时,主机 A 立刻发送一个仅携带 1 1 1 字节数据的零窗口探测报文段

tcptance.gif

假设主机 B 此时的接收窗口又为 0 0 0

  • 主机 B 就在确认这个零窗口探测报文段时,给出自己现在的接受窗口值为 0 0 0

tcptanceback.gif


主机 A 再次收到零窗口通知,就再次启动一个持续计时器

  • 当持续计时器超时,主机 A 立刻发送一个仅携带 1 1 1 字节数据的零窗口探测报文段

tcptance2.gif


假设主机 B 此时的接收缓存又有了一些存储空间

  • 于是将自己的接收窗口调整为了 300 300 300

主机 B 就在确认这个零窗口探测报文段时,给出自己现在的接受窗口值为 300 300 300

这样就打破了死锁的局面

image-20230105010616061


若主机 A 发送的零窗口探测报文段到达主机 B

  • 若主机 B 此时的接收窗口仍然为 0 0 0

    那么主机 B 根本就无法接收该报文段

  • 又怎么会针对该报文段给主机 A 发回确认呢?

实际上,TCP 规定即使接收窗口为 0 0 0 也必须接受

  • 零窗口探测报文段 \color{blue}零窗口探测报文段 零窗口探测报文段 确认报文段 \color{blue}确认报文段 确认报文段、以及 携带有紧急数据的报文段 \color{blue}携带有紧急数据的报文段 携带有紧急数据的报文段

若零窗口探测报文段丢失了,会出现怎样的问题呢?还能否打破死锁的局面么?

image-20230105011125231

  • 肯定的

因为零窗口探测报文段也有重传计时器

  • 当重传计时器超时后,零窗口探测报文段会被重传

9、习题

image-20230105011238387

在上述的举例中,为了简单起见,忽略了拥塞控制

  • 也就是认为 TCP 发送放的发送窗口等于接收方的接受窗口

image-20230105012227358

确认多少,滑动窗口就滑动多少

10、小结

image-20230105012250669

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

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

相关文章

基于微信小程序的个人健康数据管理系统小程序

文末联系获取源码 开发语言:Java 框架:ssm JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7/8.0 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.9 浏览器…

第一章.机器学习的前期准备—jupyter 更换文件路径的方法,jupyter使用方法,训练/验证/测试数据集的概念,学习方式,常见应用

第一章.机器学习的前期准备 1.1 第一章.机器学习的前期准备 1.jupyter软件的安装 说明:可以使用Anaconda软件中的jupyter软件 1).jupyter 更换文件路径的方法: ①.查找电脑中是否存在 jupyter_notebook_config.py 文件,若不存在,通过命令提…

前端最基础面试题:说说JavaScript中如何判断数据类型?

1. 基本数据类型的判定:typeof [变量名] typeof 1 // number typeof string呀 // string typeof true // boolean typeof Symbol(abc) // symbol控制台验证: 2. 引用类型 object 的判断: ① constructor ② instanceof ③ Object.prototy…

Redux与前端表格施展“组合拳”,实现大屏展示应用的交互增强

Redux 是 JavaScript 状态容器,提供可预测化的状态管理。它可以用在 react、angular、vue 等项目中, 但与 react 配合使用更加方便一些。 Redux 原理图如下,可以看到store仓库是Redux的核心,通过维护一个store仓库管理 state。state 是只读的…

JS严格模式(use strict)

javascript语法不够严谨,例如我们在项目中不用关键字去定义了一个变量a,控制台一切正常。b123;console.log(b)但是,如果开启了严格模式呢?"use strict" b123; console.log(b)此时将会报错Uncaught ReferenceError: b is…

开关电源中功率电感均方根电流是如何推导的?来自《开关电源宝典》

3.2.8 功率电感的有效电流参考“1.7.3 功率电感”章节内容,我们知道,功率电感具有温升电流、RMS电流、饱和电流、额定电流等电流参数。在后续“第5章 降压电路的应用方法”应用实例中进行功率电感选型时,需要保证所选电感的额定电流参数大于实…

自定义类型:结构体,枚举,联合(1)

tips 1. 2. 结构基础知识复习 1. 结构是一些值的集合,这些值被称为成员变量,结构的每个成员可以是不同类型的变量。 2. 结构体类型,结构体成员,结构体变量,结构体指针的创建方式 3. 初始化结构体变量的时候&…

华为开源自研AI框架昇思MindSpore应用实践:FGSM网络对抗攻击

目录一、环境准备1.进入ModelArts官网2.使用CodeLab体验Notebook实例二、对抗样本定义三、攻击方法快速梯度符号攻击(FGSM)四、数据处理五、训练LeNet网络六、实现FGSM七、运行攻击近年来随着数据、计算能力、理论的不断发展演进,深度学习在图…

老板要求总部-分部异地组网,作为IT运维怎样才能避免踩坑?

最近在开年会,老板提出2023年要全面搭建30个分公司的广域网架构,总部和分公司网络实现统一管理。但是公司原有网络架构复杂,各分支又是不同运营商接入的现状,想要实现异地组网并不容易!然而,老板还不断提出…

好用的基于vue的组织架构图组件

都是基于vue的组织架构图,有支持vue2.x和vue3.x,可自行选择使用 一、vue-okr-tree(支持vue2) 文档地址:vue2-okr-tree 这个文档里面只有使用方法,不像vue3-tree-org里面有详细的介绍和安装引入教程 1.安装与引入 n…

第一章 spring框架概述

1.Spring框架概述*Spring是轻量级的开源的JavaEE框架*可以解决企业应用开发的复杂性*有两个核心的部分:IOC、AOPIOC:控制反转,把创建对象的过程交给Spring进行管理AOP:面向切面,不修改源代码的情况下进行功能的增加*Sp…

ThreadLocal与nheritableThreadLocal的区别及使用

ThreadLocal 多线程环境中,共享变量的并发修改常常导致线程同步问题,ThreadLocal可以存储线程私有的本地变量,从而使线程之间的变量相互隔离 因为ThreadLocal在线程执行的上下文可以传递变量的特性,所以可以很好的解决变量值传递…

PostgreSQL11 | pgsql建表、改表与删表

上一篇文章 PostgreSQL11 | pgadmin4基本使用http://t.csdn.cn/PKpde已经讲解了最简单的pgadmin的数据库创建、外键等可视化的操作,以及对应的pgsql语句 这一篇文章将讲解基础的pgsql语句 建表、改表与删表 目录 建表、改表与删表 创建数据表 单字段主键 多…

12.0、VMware-Linux部署springboot项目(图文超详细教程)

12.0、VMware-Linux部署springboot项目(图文超详细教程) 第一步:启动 Linux 进入 root 用户,打开终端 输入以下命令 -> 查看 Linux 中是否已经装有 jdk ; java -version 1.如果有,需要先将原来的 jdk …

ESP-IDF:使用multimap和vector容器给新员工随机分配部门并按照部门打印

例程&#xff1a; /* 创建5个员工&#xff0c;给5个员工随机分配部门&#xff0c;然后按照部门打印员工*/ #include #include #include #include <time.h> #define SALEDEPARTMENT 1 #define RDDEPARTMENT 2 #define MEDEPARTMENT 3 class worker { public: string …

10分钟做好 Bootstrap Blazor 的表格组件导出 Excel/Word/Html/Pdf

上篇: Bootstrap Blazor 实战 通用导入导出服务(Table组件) 1.新建工程 新建工程b14table dotnet new blazorserver -o b14table将项目添加到解决方案中&#xff1a; dotnet sln add b14table/b14table.csproj使用 nuget.org 进行 BootstrapBlazor 组件安装, FreeSql sqlite…

在线阅读网站|基于Springboot+Vue开发实现小说阅读网站

作者主页&#xff1a;编程指南针 作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容&#xff1a;Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助 收藏点赞不迷路 关注作者有好处 文末获取源…

探索SpringMVC-HandlerAdapter之RequestMappingHandlerAdapter

前言 在RequestMappingHandlerAdapter的第一篇文章《探索SpringMVC-HandlerAdapter之RequestMappingHandlerAdapter-参数解析》我们从方法调用的角度提出了三个问题。前面两篇分别回答了方法入参、返回值处理这两个问题。而第三个问题则是由异常处理器负责的&#xff0c;不属于…

栈的讲解及实现(图解+代码/C语言)

今天为大家分享的是栈的模拟实现&#xff0c;本文主要讲解如何以数组的形式模拟实现&#xff0c;同时给出链表模拟实现栈的代码。 目录 图解栈的结构数组模拟栈的分步实现 创建并初始化入栈检测栈是否为空出栈获取栈顶元素获取栈内有效元素个数销毁栈 链表模拟实现栈 模拟思…

学习笔记:统计建模方法的比较分析

前言本文介绍了隐马尔可夫模型 (HMM)、最大熵马尔可夫模型 (MEMM) 和条件随机场 (CRF) 的比较分析。 HMM、MEMM 和 CRF 是三种流行的统计建模方法&#xff0c;通常应用于模式识别和机器学习问题。 让我们更详细地探讨每种方法。一、隐马尔可夫模型 (HMM)“隐藏”一词象征着只有…