【Linux从青铜到王者】tcp协议2

滑动窗口

滑动窗口是什么

上篇提到如果两端发送数据如果是一发一收那就是串行,效率很低,所以可以一次发送多个报文,一次也可以接受多个报文,可以大大的提高性能(其实是将多个段的等待时间重叠在一起了)

那么是怎么发送多个报文的呢?靠的就是滑动窗口这个大杀器

滑动窗口是什么?是为了让tcp并发地发送大量暂时不需要ACK的数据段,从而提高发送效率的解决方案(这里也涉及流量控制的解决方案,和重传机制也有关系!)

如果学习过双指针算法的同学可能听到滑动窗口这个名字很熟悉,其实这里就是类似的

之前我们说过可以把缓冲区当做一个单位大小为char的数组,然后有两个指针win_start和win_end分别指向滑动窗口的起始位置和结束位置

这样发送缓冲区就被分成了三个区域:

          滑动窗口的左边区域,处于滑动窗口的区域,滑动窗口的右边区域

分别对应已发送已确认可以直接发送但是尚未确认未发送或者没数据的区域

下图为示范例子:

  • 窗口大小就是指无需等待确认应答而可以继续发送数据的最大值。图中,窗口大小为4个段,也就是4000个字节。
  • 发送前四个段的时候, 不需要等待任何ACK, 直接发送。
  • 收到第一个ACK后, 滑动窗口向后移动, 继续发送第五个段的数据; 依次类推。
  • 操作系统内核为了维护这个滑动窗口, 需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答; 只有确认应答过的数据, 才能从缓冲区删掉——所以一个数据被发送后,不能立马被移除
  • 窗口越大, 则网络的吞吐率就越高

滑动窗口在哪里?

滑动窗口本质上就是发送缓冲区的一个区域

滑动窗口怎么理解?

【win_start,win_end】:滑动窗口!!——本质就是两个数组下标充当指针作用

win_start=确认序号

win_end=win_start(确认序号)+win(接收方的接受能力)——16位窗口大小

所谓的窗口滑动,本质就是下标移动

因为滑动窗口发送的是可以直接发送尚未确认的数据,所以要考虑对方的接受能力,所以滑动窗口的大小由对方的接受能力决定!!!(后续会有变化)

那么最开始的时候,我还没发送数据的时候,滑动窗口的大小是多大?

所以在三次握手的时候,滑动窗口的大小,双方已经协商完毕

滑动窗口的变化以及流量控制

滑动窗口可以往左移动吗?

不可以,win_start=确认序号,而确认序号=序号 +1的,所以滑动窗口只可能往左移动

滑动窗口的大小不变吗?变大?变小?为0?

当确认一个报文后又发送一个报文的时候,滑动窗口的大小就是不变的

当一次发了四五个报文,只有前面两个应答了,那么win_start+=2个报文的长度,滑动窗口也就变小了。后面全部报文都应答了,win_end+=三个报文的长度,滑动窗口也就变大了

所以不变,变大和变小都是可以的——流量控制!!!

接收方能力弱:我就发慢点

接收方能力强:我就发快点

变大变小不变都行,这才叫控制

如果滑动出去,越界了怎么办?把发送缓冲区想象成环形结构即可!!!(环形数组可以用数组来模拟实现)

这里也体现到上篇提到的如果报文发送了,还没应答,就不能丢弃,暂时存起来,存在哪?滑动窗口里

报文丢失

一次发多个数据,那么肯定会有上篇讲的丢失报文的问题,那么报文丢了怎么办?

我们可以将报文丢失分为三类:最左侧丢失,中间丢失,右侧丢失

如果发了序号2000,3000,4000,5000的四个报文,正常情况下发送方应该收到确认序号为2001,3001,4001,5001的ACK

最左侧丢失就是2001ACK没收到,那么此时后面的确认序号就不再是3001,4001,5001了,而是1001,因为确认序号的定义是该序号之前的数据,全部收到

所以连续接收到三个1001ACK,但是明明发的是2000,3000,4000,5000,所以就可以推测出是2000报文丢失了,所以会补发2000报文!!!

如果是中间丢失,也就是3001丢失,那么发送方是接收到2001ACK的,所以窗口会向右移动一个长度,此时中间丢失就变成最左边丢失,重复以上动作即可

如果是最右侧丢失,那么结果还是一样的,窗口不断右移直到丢失的报文成为最左侧,变成最左侧丢失的情况,然后重复上述操作!

总结:不管是什么丢失,最后都会变成最左侧丢失

这里涉及到一个重传机制

快重传:如果连续收到三个同样的确认序号的时候,会立即将对应的报文进行补发!!!

有人会想了,都有快重传了,听名字就挺快的,还要超时重传干什么?

细看的话会发现快重传是有条件的,要连续收到三个同样的确认序号,不是连续的话只能超时重传了

所以超时重传是兜底的,快重传是提高效率的重传策略,两者互相配合

在滑动窗口这里,可以充分体会到确认序号的的价值!!!

还有将缓冲区视为字节环形结构的作用——有了序号和确认序号,保证了可靠性——发送成功或者失败都100%知道!!!

到这里不得不赞叹tcp的设计,几个字段互相配合不仅仅保证了可靠性,还实现了效率的提升

拥塞控制

到目前为止我们讲的都是两个主机之间的,两个主机之间通信还要经过网络这一环节

假设有一天网络突然瘫痪(网络非常繁忙)了,发送的报文迟迟未被接收,那么此时要进行超时重传吗?

如果这时进行超时重传,注意此时不再是两台主机之间通信,可能有很多台主机都向你超时重传发送信息,注意此时网络已经瘫痪,超时重传等于再发一次信息,无异于压死骆驼的最后一根稻草,让网络雪上加霜

所以此时不能进行网络重传

当出现小面积丢包的时候,认为是丢包,进行超时重传

当出现大面积丢包的时候,认为是网络出现问题,不超时重传,而是拥塞控制

什么是拥塞控制呢?就是先试探,慢慢发,随着你应答的次数增多而显著提高发送的数据量

滑动窗口决定了我们单次发送数据量的多少——所以滑动窗口的大小不仅与对方的接受能力有关,还要考虑网络的状态

滑动窗口=min(拥塞窗口大小,对方的窗口大小)

拥塞窗口本质就是一个数字,当发送数据量超过拥塞窗口的时候,有很大的概率会引起网络拥塞

拥塞窗口=2^n,就是个指数函数。可以发现该函数完美切合要求,慢启动,快增长。

前期慢,增长快——前期慢是为了试探网络环境如何,增长快是为了尽快进行正常网络的通信

当拥塞窗口的值超过阈值的时候,拥塞窗口就会变成线性增长,变化规律如图所示,就不赘述

我们发送数据的时候,就是按照图片的规律来发送吗?当然不是,发送数据靠什么?靠滑动窗口?滑动窗口win_start=ack,win_end=min(拥塞窗口大小,对方窗口大小)

所以可能发送到一半就按照对方窗口的大小发送了

但是拥塞窗口必须一直在变化,因为网络的状态要一直探测

tcp的保活机制(心跳机制)

机器掉电,网线断开的时候,tcp内部有一个计时器,当超过固定时间后仍未应答则自动关闭连接,但是tcp的时间定的太长了,一般更推荐在应用层完成

listen的第二个参数

全连接队列

饭店排队场景类似

如果一个饭店里很多人用餐没有位置了,此时又新来了客人,你直接对客人说走吧没位置了,那肯定会被老板喷个狗血淋头,因为等里面的客人吃完了,如果此时又没新的客人来,高峰期的时候一些座位就会被闲置了

如果你在外面放了一些椅子,让客人在外面等,这时里面的人用完餐了,外面的人就可以直接进去用餐了,高峰期里面的位置被闲置的概率大大降低

但是你也不能在外面摆太长,比如摆个几百张,除了前面几十张等得起,后面的人要等的时间太久了,而且椅子也是占空间的,外面的地可不是都是你们店的

上面的饭店就类似应用层,客人就是连接,外面摆的椅子就是全连接队列,全连接队列不能太长

相关问题

connect参与三次握手吗?

connect参与三次握手,发送SYN请求后,双方操作系统自动完成

accept参与三次握手吗?

当一个服务器通过bind函数开始监听该套接字上的连接请求,一旦有客户端尝试建立连接,三次握手成功后,服务器端的accept调用才会返回,从全连接队列中获得一个新的套接字

所以是不参与的,是发生在三次握手之后的

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解锁人工智能学习中的数学密钥

一、启航:奠定数学基础 1. 线性代数:AI的入门语言 学习目标:掌握向量、矩阵的基本概念及运算,理解线性空间、线性变换及特征值、特征向量的意义。学习建议:从基础教材入手,如《线性代数及其应用》&#x…

【黄啊码】零代码动手创建ModelScope Agent

还没开始学习,先来回复一下,什么是Agent Agent包含的模块 好了,开始发放干货: 1、创建通义千问API (新注册用户有一定的限时免费额度) 2、登录阿里云账号,打开 DashScope管理控制台,开通 DashScope灵积模…

WinUI vs WPF vs WinForms: 三大Windows UI框架对比

1.前言 在Windows平台上开发桌面应用程序时,WinUI、WPF和WinForms是三种主要的用户界面框架。每种框架都有其独特的特点和适用场景。本文将通过示例代码,详细介绍这些框架的优缺点及其适用场景,帮助dotnet桌面开发者更好地选择适合自己项目的…

使用EasyAR打包安卓操作注意

EasyAR for Scene 4.6.3 丨Unity2020.3.15f2 打包Unity注意事项 一、默认渲染管线 官方参考链接:ARFoundation 简单注意 1.打包设置为Android平台 2.PackageName和EasyAR中保持一致 3.Scripting Backend设置为IL2CPP,以及设置为ARM64 4.取消Auto …

数据结构·红黑树

1. 红黑树的概念 红黑树,是一种搜索二叉树,但在每个节点上增加一个存储位表示节点的颜色,可以是Red或Black。通过对任意一条从根到叶子的路径上各个节点着色方式的限制,红黑树确保没有一条路径会比其他路径长出两倍,因…

秋招突击——7/29——复习{有塔游戏——关联传递性}——新作{随机链表的复制、合并K个升序链表,二叉树——二叉树的中序遍历、二叉树的最大深度、反转二叉树}

文章目录 引言复习有塔游戏——关联传递性实现复习实现参考实现 新作随机链表的复制个人实现参考实现 排序链表个人实现参考实现 二叉树章节二叉树的中序遍历个人实现 二叉树的最大深度个人实现参考实现 反转二叉树个人实现参考实现 总结 引言 旅游完回来了,今天继…

Matlab编程资源库(14)常微分方程初值问题的数值解法

一、 龙格-库塔法简介 龙格-库塔法(Runge-Kutta method)是一种常用的数值解微分方程的方法,由德国数学家卡尔龙格(Carl Runge)和马丁威尔海尔姆库塔(Martin Wilhelm Kutta)在20世纪…

IDEA 本地有jar包依赖文件,但是所有引用的jar包全部爆红

前端时间 看源码,下载源码额按钮不见了,折腾了很久,遂打算重新安装idea,但是重新安装后,发现代码全都爆红,按照晚上说的删除idea 文件夹,idea缓存删除,都不好使,但是看到…

【JavaScript】`Map` 数据结构

文章目录 一、Map 的基本概念二、常见操作三、与对象的对比四、实际应用场景 在现代 JavaScript 中,Map 是一种非常重要且强大的数据结构。与传统的对象(Object)不同,Map 允许您使用各种类型的值作为键,不限于字符串或…

机器学习算法——常规算法,在同的业务场景也需要使用不同的算法(一)

👨‍💻个人主页:开发者-曼亿点 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 曼亿点 原创 👨‍💻 收录于专栏&#xff1a…

【Vulnhub系列】Vulnhub_SecureCode1靶场渗透(原创)

【Vulnhub系列靶场】Vulnhub_SecureCode1靶场渗透 原文转载已经过授权 原文链接:Lusen的小窝 - 学无止尽,不进则退 (lusensec.github.io) 一、环境配置 1、从百度网盘下载对应靶机的.ova镜像 2、在VM中选择【打开】该.ova 3、选择存储路径&#xff0…

“数说”巴黎奥运会上的“中国智造”成果

引言:随着“中国智造”在欧洲杯上方兴未艾,在巴黎奥运会上,中国智造继续以多种形式和领域展现了其强大的实力和创新能力。以格力公开表示将为巴黎奥运村提供345台格力空调,为中国制造的清凉送至巴黎事件拉开中国制造闪亮巴黎奥运会…

浅谈取样器之调试取样器

浅谈取样器之调试取样器 JMeter的调试取样器(Debug Sampler)是一个非常实用的工具,它帮助用户在测试计划执行过程中获取详细的内部状态信息,这对于诊断脚本错误、理解变量作用域、以及确认配置是否按预期工作至关重要。调试取样器可以显示JMeter变量、属…

将gitee 上的nvim 配置 从gitee 上下载下来,并配置虚拟机

首先是下载 gitee 上的配置。 然后是 配置 tmux 然后是配置nvim . 1 在init.lua 文件中注释掉所有的与第三方插件有关的内容。 2 在packer 的文件中 , 注释掉所有的与 第三方插件有关的代码。 3 首先要保证 packer 能够正确的安装。 4 然后开始 安装 所有的插件…

【SOC 芯片设计 DFT 学习专栏 -- DFT DRC规则检查】

请阅读【嵌入式及芯片开发学必备专栏】 请阅读【芯片设计 DFT 学习系列 】 如有侵权,请联系删除 转自: 芯爵ChipLord 2024年07月10日 12:00 浙江 文章目录 概述DRC的概念Tessent DRC检查的概述时钟相关检查扫描相关检查BIST规则检查预DFT时钟规则检查 …

Git(分布式版本控制系统)(fourteen day)

一、分布式版本控制系统 1、Git概述 Git是一种分布式版本控制系统,用于跟踪和管理代码的变更,它由Linux、torvalds创建的,最初被设计用于Linux内核的开发。Git允许开发人员跟踪和管理代码的版本,并且可以在不同的开发人员之间进行…

链表篇-02.从尾到头打印链表(反转链表)

解题思路: 链表从尾到头打印链表, 我的思路是 用三个指针,第一个指针(pre)指向指向头节点的前一个位置,第二个指针(cur)指向头节点, 然后依次往后执行,第三个指针用于临时记录第二个指针的下一个位置。 代码详情: import java.…

【Code】Street-Gaussian代码复现笔记

文章目录 1. EnvironmentBug 1 2. TrainingBug 2Bug 3 1. Environment Follow the original instructions, conda create --name street-gaussians-ns -y python3.8 conda activate street-gaussians-ns pip install --upgrade pippip install torch2.1.2cu118 torchvision0.…

差分法求解 Burgers 方程(附完整MATLAB 及 Python代码)

Burgers 方程的数值解及误差分析 引言 Burgers 方程是一个非线性偏微分方程,在流体力学、非线性声学和交通流理论中有广泛应用。本文将通过数值方法求解带粘性的 Burgers 方程,并分析其误差。 方程模型 Burgers 方程的形式为: u t u u …

如何快速获取全网精准客流?揭秘不为人知的5大运营策略!

有同行所在的地方,就一定拥有咱们需要的客户。客户看的是结果,搜索的是问题,寻找的是答案。 如果没有付费流量,单纯靠搞免费流量,很多大厂的运营也会变得一文不值。一个牛逼的运营,不仅是会做付费流量&…