Linux网络:传输层协议TCP(三)滑动窗口及流量控制

news2024/11/19 19:41:23

目录

一、关于滑动窗口在TCP中的应用

1.1什么是滑动窗口,为什么要有滑动窗口

1.2滑动窗口的实现

1.3滑动窗口针对丢包重传的处理机制

二、流量控制


一、关于滑动窗口在TCP中的应用

1.1什么是滑动窗口,为什么要有滑动窗口

在上一篇博文中博主阐述了确认应答ACK策略, 对每一个对方发送的数据段报文, 接收方都要给一个 ACK的确认应答。接收方收到 ACK应答后再发送下一个数据段报文。但是这样做有一个缺点, 那就是性能较差,效率较低,尤其是数据传输往返时间较长的时候。

这样一发一收的传输方式显然性能较低, 那么如果一次发送多条数据, 从而降低传输频率,这样一来就可以大大的提高数据报文传输的性能(其实也就是将多个数据段的等待时间重叠在一起。

而我们要传输的数据如果很大,那么在TCP层,其传输能力也是有限的,而且如果这时对方的接收缓冲区已经快满的话,不能存储过多数据,且对方应用层迟迟不去接收缓冲区读取数据的话,此时我们如果依旧发送大量的数据给对方,那么会有很大的概率出现丢包的情况,这时发送方就要根据传输协议的阈值以及对方接收能力来动态的调节每次发送的数据量。这时,维护一个窗口,通过滑动窗口来控制无疑就是最好的选择。

结合我们所介绍的多条数据一起发送(实际上是在没有接收ACK情况下连续的发送好几条报文),滑动窗口就可以一次确定一段发送区间,然后分段进行发送,得到对方应答确定报文被对方接收后继续向后移动去发送还未被发送的报文。

1.2滑动窗口的实现

窗口的大小指的是无需等待确认应答而可以继续多次发送数据的最大值. 上图中的窗口大小就是4000个字节(四个段)。

刚开始发送前四个段的时候, 不需要等待任何的ACK应答,直接连续发送报文;

当收到第一个 ACK应答之后, 滑动窗口就继续向后移动, 继续发送第五个段的数据;依次往后类推;

操作系统内核为了维护这个滑动窗口, 需要开辟一个发送缓冲区来记录当前还有哪些数据没有应答; 只有确认应答过的数据, 才能从缓冲区删掉;

窗口越大, 则说明网络的吞吐率就越高;

滑动窗口也采用类似环状结构,每次通过取模类似的操作来将指针始终控制在存放数据的区间,当将后面的数据全部发送完毕后,滑动窗口会自动回绕会区间头部去处理并发送新的数据。

所以在网络较好情况下,滑动窗口的大小一般是对方接收缓冲区中剩余空间的大小

1.3滑动窗口针对丢包重传的处理机制

根据如上描述,如果真的因为特殊原因出现了丢包, 那滑动窗口该如何进行重传? 这里分以下两种情况:

情况一: 数据包已经抵达, ACK应答丢包了

 在双方都遵循TCP协议的情况下,如果情况一出现,主机B接收到了主机A的所有报文并且对所有报文都进行了ACK应答,但是应答在传输过程中丢了,这时起始问题并不大,网络正常情况下,也不会让主机A等到超时重传,因为主机B已经实实在在接收到了主机A的报文,所以确认序号是正常往后走的,这里需要重申确认序号的功能:确认序号之前的所有报文都已被接收。所以只要后面发送给主机A的ACK应答能传达到,那么主机A也可以知道在此之前的报文对方都接收到了,就不会再进行超时重传了。

比如上图所示,就算前几个应答都丢失了,但只要后面6001的应答传给了主机A,那么主机A就知道,虽然前面的应答我没有接收到但是对方的6001说明6001之前全部到达了,那只是ACK丢包了而已,而ACK本身就是为了确认数据可靠性的,本身并没有携带什么有价值的信息,所以主机A就不会再管6001之前的报文了。

情况二:数据包直接丢了

这种情况下,数据包直接丢了,是实实在在的丢包,那么没有ACK,主机A也不确定到底主机B是收到了还是没收到,此时TCP协议就起了作用。

当某一段报文段丢失之后,比如1001-2000的数据包丢了,那么发送端会一直收到1001的 ACK, 因为发送的每条报文都有自己的序号,而接收方会对接收的报文进行排序,然后按序进行处理,如果对应序号的报文丢失,那么接收方会一直重复发送该报文之前的确认序号,以此达到提醒对方丢包,就像是在提醒 发送端 "我想要的是 1001" 一样;

如果发送端主机连续三次收到了同样一个 "1001" 这样的应答, 就会将对应的数据 1001 - 2000 重新发送;

这个时候当接收端收到了序号1001的报文之后, 再次返回的 ACK应答就是7001了(因为 2001 - 7000)接收端其实之前就已经收到了, 被放到了接收端操作系统内核的接收缓冲区中;

而这种机制也被称为 "高速重发控制"(也叫 "快重传"机制)。

二、流量控制

在上面博主提到过网络资源和传输效率是有限的。

接收端处理数据的速度也是有限的。如果发送方发送端发的太快, 导致接收端的缓冲区被存储满, 这 时候如果发送端继续发送报文, 就会造成丢包, 从而引起丢包重传等等一系列连锁反应降低了网络传输的效率。因此 TCP 支持根据接收端的处理能力及接收缓冲区大小, 来决定发送端的发送速度. 这个机制就叫做流量控制(Flow Control);

接收端将自己可以接收的缓冲区大小(也就是接收缓冲区中剩余的大小)放入TCP 首部中的 "窗口大小" 字段, 在发送ACK应答时携带通知发送端;

窗口大小的字段越大, 说明网络的吞吐量就越高;

当接收端一旦发现自己的缓冲区快满了时, 就会将窗口大小字段设置成一个更小的值通知给发送端;

发送端接受到这个窗口之后, 就会减慢自己的发送速度;

如果接收端缓冲区一旦满了, 就会将窗口大小置为 0; 这时发送方就不再发送数据, 但是需要定期发送一个窗口探测数据段, 时刻得知对方缓冲区是否有剩余空间,使接收端把窗口大小告诉发送端。

那么问题来了, 16位二进制位所存储的数字最大表示65535, 那么 TCP 窗口最大就是 65535 字节么? 实际上, TCP 首部 40 字节选项中还包含了一个窗口扩大因子 M, 实际窗口大小是窗口字段的值左移了M 位;我们可以根据16位中存储的值再左移M得出实际的大小。

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

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

相关文章

植物神经紊乱拜拜啦! 6招让你心情美美哒,放松到飞起~

Hey宝贝们,是不是有时候觉得心里的小宇宙🌌乱糟糟的,像是有一群小精灵🧚‍♀️在跳舞,却偏偏踩不到点上?没错,这可能就是植物神经紊乱在作祟啦!别怕,我这就给你支几招&am…

Nginx系列-12 Nginx使用Lua脚本进行JWT校验

背景 本文介绍Nginx中Lua模块使用方式,并结合案例进行介绍。案例介绍通过lua脚本提取HTTP请求头中的token字段,经过JWT校验并提取id和name信息,设置到http请求头中发向后段服务器。 默认情况下,Nginx自身不携带lua模块&#xff0…

Transformer中的Multi-head Attention机制解析——从单一到多元的关注效益最大化

Transformer中的Multi-head Attention机制解析——从单一到多元的关注效益最大化 Multi-head Attention的核心作用 组件/步骤描述多头注意力机制(Multi-head Attention)Transformer模型中的关键组件,用于处理序列数据功能允许模型同时关注到…

Vue2从基础到实战(指令篇)

Vue中的常用指令! 概念:指令(Directives)是 Vue 提供的带有 v- 前缀 的 特殊 标签属性。 vue 中的指令按照不同的用途可以分为如下 6 大类: 内容渲染指令(v-html、v-text) 条件渲染指令&…

昇思25天学习打卡营第1天|快速入门-构建基于MNIST数据集的手写数字识别模型

非常感谢华为昇思大模型平台和CSDN邀请体验昇思大模型!从今天起,我将以打卡的方式,结合原文搬运和个人思考,分享25天的学习内容与成果。为了提升文章质量和阅读体验,我会将思考部分放在最后,供大家探索讨论…

04 | 深入浅出索引(上)

此系列文章为极客时间课程《MySQL 实战 45 讲》的学习笔记! 索引的常见模型 可以提供查询效率的数据结构有很多,常见的有三种:哈希表、有序数组、搜索数。 哈希表是一种以 key-value 形式存储的数据结构。输入一个 key,通过固定…

Markdown使用~~pandoc插件安装

目录 1.两大秘密武器 2.vscode创作 3.Typora的安装 4.pandoc安装 4.1百度网盘 4.2按照说明安装 4.3到达github里面下载 4.4选择对应版本 4.5进入偏好设置 4.6对于导出的路径进行配置 5.Typora和vscode的对比 6.如何正确的学习这个Typora软件 7.一点相关的说明 1.两…

做一个能和你互动玩耍的智能机器人之三

内容节选自英特尔的开源项目openbot的body目录下diy下的readme,这是一个组装和连线方式的说明文档,接线需要配合firmware固件使用,固件代码的接线柱是对应的。 body目录内部十分丰富,主要介绍了这个项目的背景和硬件以及如何让他…

datawhale逻辑推理赛题01

跟着datawhale参加了逻辑推理赛题,这个是一个大模型比赛入门非常好的比赛,可以帮助我们更快的上手大模型相关的业务 我参加的是天池的这个比赛,跟着datawhale官方的baseline01已经上分0.6498,是一个非常好的开始 后续我讲继续跟着…

java项目中添加SDK项目作为依赖使用(无需上传Maven)

需求: 当需要多次调用某个函数或算法时,不想每次调用接口都自己编写,可以将该项目打包,以添加依赖的方式实现调用 适用于: 无需上线的项目,仅公司或团队内部使用的项目 操作步骤: 以下面这…

Linux---进程(2)

目录 查看进程 查看进程pid 系统目录查看 理解当前工作目录用途 fork创建进程 存在问题 问题解决 问题一 问题二 本文介绍进程标识符的相关知识以及创建子进程。 查看进程 指令就是可执行程序,每次运行时,都需要被加载到内存,运行…

动物之森-小红书2024笔试(codefun2000)

题目链接 动物之森-小红书2024笔试(codefun2000) 题目内容 塔子哥最近在玩一款叫做“动物之森”的四字开放游戏世界。由于塔子哥氪金了,所以他在游戏中拥有很多个宝箱,每个宝箱里都装着一些他收集的宝石。每一种类型的宝石都有不同的作用。 有一天&…

java--jvm虚拟机(都是要点)

请带着以下问题,学习并理解jvm 问题一: 为什么fullGC会对系统性能有影响?youngGC却几乎没有? 问题二: outofmemory是什么异常?什么时候会出现?如何处理? 问题三: 线程…

鸿蒙 HarmonyOS NEXT端云一体化开发-云函数篇

前言 TODO:新建项目和应用,开通云函数服务(AGC)端侧开发:Arkts界面开发云测开发:云函数、认证服务、云存储、云数据库 一、登录 地址:https://id1.cloud.huawei.com/CAS/portal/loginAuth.htm…

Nginx周末部署

背景 Nginx是本人学习的一类中间件,上次完成了vue的搭建,所以顺便把项目加入Nginx吧 1. 镜像拉取与测试 查询dockerHub,选择最新最稳定的版本 docker pull nginx:stable-perl 执行下载 docker run -d --name mynginx -p 8080:80 -v D:\IM…

【Kubernetes】配置管理(一):ConfigMap

配置管理(一):ConfigMap 1.配置管理2.使用 ConfigMap 管理 Pod 的配置信息2.1 创建 ConfigMap2.1.1 在命令行中通过指定 ConfigMap 的参数进行创建2.1.2 通过指定的配置文件创建 ConfigMap2.1.3 通过一个文件内的多个键值对创建 ConfigMap2.1…

C++数据结构重要知识点(3)(红黑树及其插入操作)

1.红黑树和AVL树的区别 红黑树和AVL树都是平衡树,都是为了解决二叉搜索树的劣势。其中,AVL树的左右子树的高度差不超过1,而红黑树的最长路径不超过最短路径的二倍,也就是说,红黑树是一种近似平衡,而AVL树是…

【设计模式】(万字总结)深入理解Java中的创建型设计模式

1. 前言 在软件开发的世界里,设计模式是一种被广泛接受并应用的解决方案。它们不仅仅是代码的设计,更是对问题的思考和解决的方法论。在Java开发中,特别是在面向对象的编程中,设计模式尤为重要。创建型设计模式,作为设…

JavaScript安全编程宝典【万字详解】

文章目录 简介基本说明特点两种使用方式在script中写使用script标签引入JS文件 数据类型介绍特殊值 运算符算数运算符赋值运算符逻辑运算符:条件运算符 数组的定义基本使用数组的遍历 函数含义函数定义方式基本语法代码示例 细节和注意事项 自定义对象Object形式{} …

解决mysql数据库表读取中文乱码问题

本文目录 0、省流1、问题出现2、问题排查3、结论 0、省流 在服务器上创建数据库服务时,使用的sql脚本加载的数据库表,其中脚本中有一些预设的测试数据包含中文汉字,由于linxu服务器控制台默认编码是lantin1,导致中文通过该编码方…