滑动窗口的理念

news/2024/11/22 16:48:49/

这三个控制在tcp中是重要的控制程序,这些控制是为了让我们的TCP协议在网络传输中变得可靠与高效。

这三个控制其实是相辅相成的,也是高度解耦的控制模块。

细分的话,我们的滑动窗口与流量控制属于终端的控制,而拥塞控制,是为了防止为了拥塞。

滑动窗口

滑动窗口大小认识

如果主机与主机的交流是发送完报文就必须等待ACK应答才可再发送报文,这是不合理的,会将是极大的浪费资源的表现。

所以我们需要同时发送多次报文给对方,而且需要保证数据丢包后必须保证在对应的确认应答前,必须保护数据在一段数据不会被修改覆盖,保证需要重发时能够找到并重新发送。

现在看图是不是怪怪的,发送确认序号:1001,却发送了4001~5000,奇怪吧?

这时候就出现了滑动窗口的概念。

滑动窗口是可以接收1001确认序号而不影响发送问题的。

我们先再一次介绍一下序号和确认序号。

我们将发送缓冲区的每个字节编号,将对应的数据发送

然后我们包一大个报文数据看成一个一个段。而我们的滑动窗口就是一些连续的段。

//发送缓冲区伪代码
struct 滑动窗口
{sendbuff[NUM];//发送缓冲区int win_start;//滑动窗口头int win_end;  //滑动窗口尾//....
}

win_start与win_end,是两个整型(也可以说是地址下标),我们把整个发送方的发送缓冲区中定义一块区域为滑动窗口,这是一个灵活的窗口,他的大小由win_start到win_end中间包含的范围被我们称之为滑动窗口,滑动窗口的数据可以同时全部发送,不必等待应答。

滑动窗口的大小并非固定,每次接收到确认应答后,我们的滑动窗口就会每次调整(除非是窗口探测报文这属于流量控制后面讲),win_start根据应答报文的确认序号更新,然后win_end=win_start+接收端的接收能力(这个说法有点问题);

滑动窗口调整的情况有许多,我们举几个例子证明滑动窗口并不是意味的向右固定大小

  1. 正常数据接收的情况滑动窗口会向后移动。
  2. 在ACK报文接收后,发现接收端接收能力变弱接收到的报文还未处理,未报文堆积在了接收缓冲区中,这就意味着接收端的接收能力减低了,这个时候就是需要调整我们滑动窗口大小。比如接收ACK前start:1001,end:5000然后再接收ACK,ACK中确认序号为3001,16位窗口大小与上一次TCP报文滑动窗口对比较小,导致了start向右移动,end可能向不变甚至向左,这就导致了滑动窗口变小了,我们下次可发送的报文变少了。
  3. 在一次大量的报文发送后,接收端数据的接收缓冲区直接被占满了,在不丢包的情况下,对 最后一次接收的报文发送应答,该应答报文中将窗口大小标识成0,服务端将不在发送数据。

正常移动:

接收到了2001~3000的应答报文3001、16为窗口大小:3000。

窗口减小:

接收到了3001~4000的应答报文4001、16为窗口大小:2000

窗口大小为0:

接收到了5001~6000的应答报文6001、窗口大小为0。

这里阐述了2个知识

  1. 当没有收到5001应答报文却收到了之后的6001应答报文,发送方可以认为应答包丢了,或者接收方为了效率只发送了最后序号的应答报文。当是这是不影响的,这也是证明了6001之前的报文全部都被收到了,允许滑动窗口移动
  2. 是否允许滑动窗口为0呢?这是允许的。

注意,虽然滑动窗口为0,无法再次发送携带数据的报文,但是会发送探测窗口报文(探测对方接收能力的报文),对应探测报文的确认应答返回,我们就知道了对端现在是否有剩余的空间允许我发送报文。当然接收方一旦倒腾出剩余也会发送窗口更新报文,通知我可以发送带数据报文了。

我们知道当一个报文长时间未得到应答,就会发起超时重传。

超时重传与滑动窗口

这个时间间隔并不是固定的,这个不能太长也不能太短否则会影响效率或者数据紊乱,一般而言是以网络为标准的,但是我们并不知道网络是否通畅,所以等待超时重发的时间不能是固定的。Linux中(BSD Unix和Windows也是如此), 超时以500ms为一个单位进行控制, 每次判定超时重发的超时 时间都是500ms的整数倍。

也就是说:

为什么说我们的滑动窗口有所帮助呢?因为在未收到该报文应答或者之后报文的应答的时候,滑动窗口会保护该报文,在用户层写入数据是不允许覆盖滑动窗口的数据,只会覆盖的到应答的报文。滑。

用户成写入代码只会写入空段和被应答了的报文位置,在滑动窗口内的报文都属于可能会重发数据,需要妥善保护。

快重发机制

配合对端快速发现丢包情况,不必等待超时重传机制,直接再次发送丢包报文,这也是一种滑动窗口高效的行为,作为为TCP协议在可靠中并且提升了效率。

client同时发送多条报文,1~1000、1001~2000、2001~3000、3001~4000、4001~5000。

server端在接收的报文的同时也会检查结束到的报文序号是否与实际大小连贯,一旦发现某一报文跨度大,立刻发生缺失部分的报文数据,在发生方多次收到之前报文的ACK应答(一般3次)然后就会得知,我的ACK应答后的第一个报文丢了,我需要重新发送这个报文了。

 那么有这么牛的机制,还需要超时重复吗?需要,这是相辅相成的机制。

在这里说明:如果是频繁的TCP协议交流的情况下,快重发机制优先于超时重传机制,但是如果是低交流状态下,我们需要超时重传做为我们最后的可靠机制。


http://www.ppmy.cn/news/1114371.html

相关文章

Spring 框架中用到的设计模式。常见设计模式总结以及其作用简要说明

Spring 框架中使用了许多设计模式,以下列举⼀些⽐较重要的: 重点 :单例、代理、⼯⼚、责任链 1、单例模式: Spring 的 Bean 默认是单例模式,通过 Spring 容器管理 Bean 的⽣命周期,保证每个 Bean 只被创…

C++ 太卷,转 Java?

最近看到知乎、牛客等论坛上关于 C 很多帖子,比如: 2023年大量劝入C 2023年还建议走C方向吗? 看了一圈,基本上都是说 C 这个领域唯一共同点就是都使用 C 语言,其它几乎没有相关性。 的确是这样,比如量化交…

按键点亮led灯

原理图: K0这个按键按下时,开发板D1这个灯亮,松开,灯灭 代码如下: #include "stm32f4xx.h" void LED_Init(void) {//1.定义一个GPIO外设的结构体变量 GPIO_InitTypeDef GPIO_InitStructure;//RCC_AHB1PeriphClockCmd(RCC_AHB1Pe…

【微信小程序】文章设置

设置基本字体样式:行高、首行缩进 font-size: 32rpx;line-height: 1.6em;text-indent: 2em;padding: 20rpx 0;border-bottom: 1px dashed var(--themColor); 两端对齐 text-align: justify; css文字两行或者几行显示省略号 css文字两行或者几行显示省略号_css…

07. Skywalking 服务监控和链路追踪

Spring Cloud 微服务系列文章,点击上方合集↑ 1. 简介 SkyWalking是一个针对分布式系统的应用程序性能监视工具和分析平台,它是基于Java Agent探针的技术,对服务进行监控和追踪,具有零侵入性特点。 SkyWalking对运行中的服务进…

JavaWeb的基本概念

一、Web基本概念 Web的基本结构: 1.客户端的概述 1.1. 客户端的作用 与用户进行交互,用于接收用户的输入(操作)、展示服务器端的数据以及向服务器传递数据 1.2. 常见的客户端 PC端网页: 移动端: Iot设备: 2…

记一次线程堵塞(挂起)导致消息队列积压

1 背景 A服务作为生产者,每天发送上千万的mq消息,每一个消息包含500个用户ids数据。B服务作为消费者,接受MQ消息并通过http调用第三方请求进行业务处理,消费组启用了rabbitmq的多线程消费组,一个实例并发40个mq消费者…

OJ练习第176题——第二高的薪水

第二高的薪水 力扣链接:176. 第二高的薪水 题目描述 示例 MySQL select max(salary) as SecondHighestSalary from Employee where salary ! (select max(salary) as salary from Employee); #去掉最大后,再去取最大,就是第二大select (s…