首页 > 系统相关 >Linux网络:传输层协议TCP(三)滑动窗口及流量控制

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

时间:2024-07-28 18:26:31浏览次数:19  
标签:窗口 ACK 报文 TCP 发送 Linux 传输层 滑动 应答

目录

一、关于滑动窗口在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得出实际的大小。

标签:窗口,ACK,报文,TCP,发送,Linux,传输层,滑动,应答
From: https://blog.csdn.net/2201_75880188/article/details/140732462

相关文章

  • Linux内核-异常输出调用栈CallTrace与Ftrace工具集
    1dump_stack函数打印内核调用堆栈。举个例子:我们定义四个函数aaa、bbb、ccc、ddd,然后bbb中调用aaa,ccc中调用bbb,ddd函数谁都不调用。在入口函数中,我们调用ccc与ddd函数,看看堆栈打印效果如何:#include<linux/module.h>#include<linux/kernel.h>#include<linux/init.h>#incl......
  • Blender 4.2 LTS (macOS, Linux, Windows) - 开源 3D 创意软件 (渲染 建模 雕刻)
    Blender4.2LTS(macOS,Linux,Windows)-开源3D创意软件(渲染建模雕刻)创造的自由Blender获得GNUGPL许可,由其贡献者拥有。因此,Blender永远是免费和开源软件。使命以免费/开源软件的形式将世界上最好的3DCG技术交到艺术家手中。想象每个人都应该自由地创......
  • Linux——CPU占不上去的解决办法
    一、将调节器升至performance:1.1查看当前的调节器:cat/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor如果不是performance,则进入root账户1.2进入root账户先进入管理员账户输入命令:suroot如果没有root账号,则参考博客:Linux系统下的root用户初始密码设......
  • Linux——手动清理内存缓存
    前言:使用free-m命令可以查看内存缓存。一、方法1.1先进管理员账户,然后进root账户1.2运行下面的命令:syncecho1>/proc/sys/vm/drop_caches#清空目录项缓存echo0>/proc/sys/vm/drop_caches#还原默认配置,这一步如果出错,则不用管sync二、小贴士......
  • linux服务器使用docker部署ES相关记录
    ES/可视化工具Kibana/ik分词器最好使用相同版本部署,实在找不到资源可基于ES版本,其余可向下兼容找最高版本docker创建网络因为我们还需要部署kibana容器,因此需要让es和kibana容器互联。这里先创建一个网络:dockernetworkcreatees-netES配置文件夹数据卷挂载:需先复制config......
  • 【Linux应用编程】Day10_进程 一文详细剖析进程,从基本概念到创建再到进程操作直至消亡
    进程详细剖析进程,包括以下内容:⚫程序与进程基本概念;⚫程序的开始与结束;⚫进程的环境变量与虚拟地址空间;⚫进程ID;⚫fork()创建子进程;⚫进程的消亡与诞生;⚫僵尸进程与孤儿进程;⚫父进程监视子进程;⚫进程关系与进程的六种状态;⚫守护进程;⚫进程间通信概......
  • 如何在 Python 中从 Milesight TrafficX 摄像头、Post(MQTT、TCP/IP、HTTP) 获取数据?
    你好,祝你度过愉快的一天或一夜,我有这个MilesightTrafficX摄像头已启动并正在运行,仪表板中有一个名为POST的设置,您可以在下图中看到:我想要的是知道如何设置这些设置(基于实际上我的意思是)能够在我的Python代码中接收数据。无论协议如何,数据都将如下所示:......
  • Linux用户和权限
    文章目录Linux用户和权限root用户和普通用户root用户(超级管理员)用户管理su和exit命令sudo命令为普通用户配置sudo认证用户组管理查看用户所属组创建以用户的时候指定组添加已经存在用户到指定组查看权限限制认知权限信息rwx修改权限控制chmod示例权限的数字序号chown......
  • 【linux】【设备树】具有 GPIO 控制器和连接器的硬件配置的备树(Device Tree)代码讲解
    具有GPIO控制器和连接器的硬件配置的备树(DeviceTree)代码讲解背景-学习Linux设备树代码soc{soc_gpio1:gpio-controller1{#gpio-cells=<2>;};soc_gpio2:gpio-controller2{#gpio-cells=<2>;};};connector:connect......
  • 谈一谈我使用 Kali Linux 作为主力系统的感受
    我使用KaliLinux也有一年多的时间了,由于我习惯了Linux/UNK的环境,所以我的电脑上只有一个系统,那就是kaliLinux。是的,你没有听错只有一个KaliLinux作为主力系统没有包含Windows,使用KaliLinux作为主力系统是方便学习Linux与网络安全相关知识。这是肯定就有人问了:你......