协议栈——收发数据(拼接网络包,自动重发,滑动窗口机制)

目录

协议栈何时发送数据~

数据长度

IP模块的分片功能

发送频率

网络包序号~利用syn拼接网络包ack确认网络包完整

确定偏移量

服务器ack确定收到数据总长度

序号作用

双端告知各自序号

协议栈自动重发机制

大致流程

ack等待时间如何调整

是否需要等待收到ack号后在发送数据~滑动窗口

合并ack号和窗口大小

总结


1.发送方协议栈根据DNS提供的服务器ip端口确定和服务器通信使用的socket套接字, 填充tcp头部信息(发送接受方ip端口信息),将syn设置为1,修改当前socket状态为正在连接

2.发送方委托ip模块发送给服务器的ip模块。服务器的ip模块再给到服务器的tcp模块,根据头部信息找到发送发要连接的socket并填入对应的客户端ip端口,接着创建tcp头部信息(发送和接收方ip端口)此时的发送方是服务器,并填充syn报文值为1(代表链接成功)和一个ack等于1的报文(代表网络包和序号都收到)委托服务器ip模块发送(建立连接的确认过程文末讲解)

3.客户端收到后完善socket中的服务端ip地址端口信息,判断服务端返回的syn是否为1来确定是否链接成功 接着设置socket状态为连接完毕;最后 向服务端模块在发送一个ack报文1确认网络包收到(tcp头部信息还是必须要填写的)

协议栈何时发送数据~

建立连接后应用就可以和服务端进行通信了,应用发的数据会缓存到协议栈中,但是何时发送呢?有两种情况,下面介绍

数据长度

应用可以指定发送数据的大小,如果协议栈收到发送指令就进行发送的话,不可控而且效率低;因此协议栈内部会指定一个长度,当达到长度后在进行发送,此前发送的数据保存到缓冲区中。

这个长度就是mtu(包含了tcp,ip头部控制信息);除去网络包的头部信息后叫做真实数据的最大传输单元,叫做mss。

MTU:Maximum Transmission Unit,最大传输单元

头部信息是固定长度,MTU长度又是固定的,因此mss可知。

图中列出的是TCP头部,同理UDP也是一样将TCP头部换为UDP头部也一样

MTU:以太网中传输的一个网络包的最大数据长度,一般为1500字节。

MSS:除去TCP/UDP模块的头部控制信息之后,一个网络包所能容纳的数据的最大长度。

报头,起始分界符,FCS是协议栈下层的网卡模块添加的,网卡模块介绍。

IP模块的分片功能

image.png

我们来回顾下,协议栈的TCP和UDP模块填充各自模块的头部控制信息后,交给IP模块去发送数据,最后一层是IP模块,因此IP模块发送的数据长度也就是协议栈发出的数据长度。

TCP/UDP模块发送的数据肯定超过了以太网和通信线路的最大传输长度也就是MTU,这个时候IP模块就会对来自TCP/UDP模块的数据进行分片,在这篇文章中的分片重组进行了介绍。

接下来举个例子看下UDP模块可以发送的最大数据长度协议栈最终发出去的数据长度(也即IP模块发出去的数据长度) 是如何变化的(TCP也一样):

UDP模块可发送的最大传输数据长度是IP包的最大长度减去IP头部和UDP头部。IP包的最大长度为16比特(2的16次方-1)也就是65535字节,不考虑其他可选字段的话 IP头部最大长度为20字节,UDP头部是8字节,也就是UDP可传输最大长度为65507字节,超过了协议栈所规定的最大传输长度MTU 1500字节,因此需要使用IP模块的分片功能进行切割。,关于切割分片和重组分片请查看上面提到的文章有详细介绍。

可以看到TCP模块和UDP模块所规定的最大数据长度和协议栈最终发出的数据长度之间经过了IP模块的分片功能处理。也很好理解,越往底层传输的数据量越小,总不能让上层传输的是0101或者数据长度特别小的数据吧(使用者也不方便),越往下每一层都进行切割最后切割到可以在网线中传输的0101信号。

发送频率

除了考虑数据长度外,还有一个因素要考虑,就是应用发送数据的频率。

应用程序发送数据的频率不高的时候,如果每次都等到长度接近MSS时再发送,可能会因为等待时间太长而造成发送延迟,这种情况下,即便缓冲区中的数据长度没有达到MSS,也应该果断发送出去。为此,协议栈的内部有一个计时器,当经过一定时间之后,就会把网络包发送出去。

大致流程:

因此上层应用程序发送的数据会放到协议栈的缓冲区中,当满足上面两个因素条件之一时(应用程序也可以指定是否立即发送数据还是按照协议栈的规则判断时机)就可以发送数据了,首先切割mss为单位的数据块,在每个数据库开头都加上头部控制信息:

拆分示意图:协议栈的TCP模块负责添加tcp头部信息,接着委托协议栈的ip模块检查是否需要切片然后发送消息,ip模块会再分片后的包中添加ip头部和mac头部信息

网络包序号~利用syn拼接网络包ack确认网络包完整

上面说过网络包会拆分,那么服务器是怎么知道该怎么拼接这些网络包还原成最初的数据呢?答案是通过序号

确定偏移量

当拆分数据拼接成网络包的时候,会将这块数据相对于起始数据的偏移字节算出来携带到tcp头部;除此之外还会携带数据包的总长度

网络包的数据长度不是放到tcp头部中, 因为用整个网络包的长度(固定的mss)减去头部的长度就可以得到数据的长度,所以接收方可以用这种方法来进行计算。有了上面两个数值,我们就可以知道发送的数据是从第几个字节开始,长度是多少了。

服务器ack确定收到数据总长度

接收方会将到目前为止接收到的数据长度加起来,计算出一共已经收到了多少个字节,然后将这个数值写入TCP头部的ACK号中发送给发送方。

序号作用

序号的作用:上面的偏移量是携带到tcp头部中,很容易就会拿到自行还原数据破解的;因此在传递过程中每个包的数据长度都要进行基于某个值偏移,也就是将原来的偏移量要加上序号。

如第一个包默认的偏移量本来是0,序号值是666,那么现在添加序号之后第一个网络包的偏移量就是666

这样对方就搞不清楚偏移量到底是从多少开始计算的。

实现这种方式需要在开始收发数据之前将初始值告知通信对象。同样服务端也需要告知序号值这样客户端就知道该如何拆分。这个偏移量就是序号值

双端告知各自序号

那么什么时候把这个初始序号值发送给对方呢?


在发送连接的阶段中会将syn设置为1, 在将SYN设为1的同时,还需要同时设置序号字段的值,而这里的值就代表序号的初始值。这个syn就是通过告知序号值用于后面通信步调一致(知道每个网络包头部的偏移量是基于序号值+当前网络包相对于数据头部的偏移量),同样第二个阶段服务器返回syn1也是告知客户端之后发送包的序号值;同时发送ack数值告知客户端数据是否发送完整(需要利用客户端传过来的序号值,偏移量减去序号就是真正的偏移量了);客户端收到后同样也需要向服务端发送ack来确认服务端发过来的数据是否完整(服务端发送syn1的时候将服务端的序号也发送了过来,也是用的这个序号来拼接服务端发送过来的数据)

这个就是大致的网络包拼接流程:


协议栈自动重发机制

自动重发机制:协议栈会在收到ack号确认之前中会存放发送的数据,如果某一个ack号没有发送过来就会重发这个数据。

大致流程

这样一来,无论网络中发生任何错误,协议栈都可以发现并采取补救措施(重传网络包) 。反过来说,有了这一机制,就不需要在其他地方对错误进行补救了。

因此,网卡、集线器、路由器都没有错误补偿机制,一旦检测到错误就直接丢弃相应的包。应用程序也是一样,因为采用TCP传输,即便发生一些错误对方最终也能够收到正确的数据,所以应用程序只管自顾自地发送这些数据就好了。不过,如果发生网络中断、服务器宕机等问题,那么无论TCP怎样重传都不管用。这种情况下,无论如何尝试都是徒劳,因此TCP会在尝试几次重传无效之后强制结束通信,并向应用程序报错


ack等待时间如何调整

ack等待时间也叫超时时间,如果协议栈发送数据等待ack的返回这段时间超过了超时时间,就会重新发送这个网络包。

但是网络信号是可以改变的,所以超时时间也应该和网络信号的好坏动态调整;并且网络信号差的时候不仅仅只是重发一个包这么简单后面的所有网络包都会收到影响(这个和安卓的anr排查差不多)

这个等待时间是根据ACK号返回所需的时间来判断的。具体来说,TCP会在发送数据的过程中持续测量ACK号的返回时间,如果ACK号返回变慢,则相应延长等待时间;相对地,如果ACK号马上就能返回,则相应缩短等待时间。

是否需要等待收到ack号后在发送数据~滑动窗口

现在的链路是 客户端服务端确认好端口ip后就开始通信了,客户端每次发送数据包携带数据长度信息 服务端返回ack信息确认是否完整收到(反过来也是一样的流程)

但是有个缺点 就是接收方必须等到发送方返回ack才能继续传输这会增加延时降低通信效率

所以采用滑动窗口的方式。客户端只管发送 不管是否收到ack报文 。

所谓滑动窗口,就是在发送一个包之后,不等待ACK号返回,而是直接发送后续的一系列包。这样一来,等待ACK号的这段时间就被有效利用起来了。

这样虽说提高了效率但是如果不等返回ACK号就连续发送包, 服务端的处理缓冲区会造成背压问题 (发送包的频率超过接收方处理能力的情况)。

发送的数据会存储在接收方的缓冲区中,之后取出来处理拼接ack号,如果什么都不管一直发送,缓冲区的数据会溢出,某些数据就会被放弃,这个肯定不是想要的结果。因此需要出一种机制能够知道对方缓冲区可以接受多少数据,根据这个值来判断是否继续发送,当服务器的缓冲区数据处理后,也需要告知客户端(通过tcp头部中的窗口字段)

图示:

合并ack号和窗口大小

如果接收方可以告知发送方当前可以容纳多少数据呢?发送方自己判断已发送的数据是不是到达极限从而暂停 当接收方处理数据时再通知客户端当前缓冲区容纳数据客户端在发送,这样是不是完美了?

并不是,如何确定ack和发送缓冲区数量的包呢?是分开发送吗还是合并 如果每次都携带缓冲区数量是不必要的 发送方知道后自己就可以判断是否达到缓冲区处理极限决定是否发送之后数据,那分开呢?又会降低效率 增加包的数量无疑会导致延迟效率下降


因此 这两个得合并但是不能每次都发,所以加了个延时的操作。

分为以下这几种情况

  • 假如我等待发送ack数据时正好服务器处理了数据缓冲区容量更新需要通知到客户端这时候合并 就可以了。
  • 再比如我处理完数据了 等待一段时间如果ack也要发送也用合并发送
  • 并且如果需要连续发送缓冲区的数量时说明处理速度很快只要同步最后一次的缓冲区可用数量即可(比如200---400--600)等待一段时间发生减少包数量
  • 需要连续发送ack时也是一样 说明客户端连续发送数据 接收方这边等待一段时间之后直接把刚收到的数据总和返回给客户端就行

通过延时解决合并不必要和独立数量多的缺点 具体延时根据实际情况判断(很多时候服务器处理速度很快几乎发送完数据就能立马处理完不需要缓冲区数量这个信息)

总结

协议栈会检查收到的数据块和TCP头部的内容,判断是否有数据丢失,如果没有问题则返回ACK号。然后,协议栈将数据块暂存到接收缓冲区中,并将数据块按顺序连接起来还原出原始的数据,最后将数据交给应用程序。具体来说,协议栈会将接收到的数据复制到应用程序指定的内存地址中,然后将控制流程交回应用程序。将数据交给应用程序之后,协议栈还需要找到合适的时机向发送方发送窗口更新。

原文链接:协议栈——收发数据(拼接网络包,自动重发,滑动窗口机制) - 掘金 (juejin.cn)

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

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

相关文章

色彩一致性自动处理方法在遥感图像中的应用

前言 在获取卫星遥感影像时,由于受不均匀的光照、不同的大气条件和不同的传感器设备等因素的影响,遥感影像中会存在局部亮度和色彩分布不均匀的现象,下面是在BigMap地图下载器中收集的几幅谷歌卫星影像,像下面这种都是拼接好的影像…

python对RabbitMQ的简单使用

原文链接:https://blog.csdn.net/weixin_43810267/article/details/123914324 RabbitMq 是实现了高级消息队列协议(AMQP)的开源消息代理中间件。消息队列是一种应用程序对应用程序的通行方式,应用程序通过写消息,将消…

图像处理与计算机视觉--第五章-图像分割-霍夫变换

文章目录 1.霍夫变换(Hough Transform)原理介绍2.霍夫变换(Hough Transform)算法流程3.霍夫变换(Hough Transform)算法代码4.霍夫变换(Hough Transform)算法效果 1.霍夫变换(Hough Transform)原理介绍 Hough Transform是一种常用的计算机视觉图形检验方法,霍夫变换一…

【vue3】wacth监听,监听ref定义的数据,监听reactive定义的数据,详解踩坑点

假期第二篇,对于基础的知识点,我感觉自己还是很薄弱的。 趁着假期,再去复习一遍 之前已经记录了一篇【vue3基础知识点-computed和watch】 今天在学习的过程中发现,之前记录的这一篇果然是很基础的,很多东西都讲的不够…

【Kafka专题】Kafka集群架构设计原理详解

目录 前言前置知识课程内容一、Kafka的Zookeeper元数据梳理1.1 zookeeper整体数据1.2 Controller Broker选举机制1.3 Leader Partition选举机制1.4 Leader Partition自动平衡机制*1.5 Partition故障恢复机制1.6 HW一致性保障-Epoch更新机制1.7 总结 学习总结感谢 前言 Kafka的…

数学建模Matlab之数据预处理方法

本文综合代码来自文章http://t.csdnimg.cn/P5zOD 异常值与缺失值处理 %% 数据修复 % 判断缺失值和异常值并修复,顺便光滑噪音,渡边笔记 clc,clear;close all; x 0:0.06:10; y sin(x)0.2*rand(size(x)); y(22:34) NaN; % 模拟缺失值 y(89:95) 50;% 模…

竞赛选题 机器视觉 opencv 深度学习 驾驶人脸疲劳检测系统 -python

文章目录 0 前言1 课题背景2 Dlib人脸识别2.1 简介2.2 Dlib优点2.3 相关代码2.4 人脸数据库2.5 人脸录入加识别效果 3 疲劳检测算法3.1 眼睛检测算法3.2 打哈欠检测算法3.3 点头检测算法 4 PyQt54.1 简介4.2相关界面代码 5 最后 0 前言 🔥 优质竞赛项目系列&#x…

【Java 进阶篇】JDBC PreparedStatement 详解

在Java中,与关系型数据库进行交互是非常常见的任务之一。JDBC(Java Database Connectivity)是Java平台的一个标准API,用于连接和操作各种关系型数据库。其中,PreparedStatement 是 JDBC 中一个重要的接口,用…

RAID知识点总结

目录 RAID类型 RAID的数据组织及存取方式 RAID热备与重构 RAID逻辑卷 常见的RAID RAID0 RAID 1 RAID3 RAID 5 RAID 6 RAID组合 RAID 10 RAID 50 总结 RAID技术对比 RAID的应用场景 RAID2.0 使用RAID2.0的原因 RAID2.0的发展 RAID2.0技术:两层虚拟…

K8s架构简述

以部署一个nginx服务说明kubernetes系统各个组件调用关系: 一旦kubernetes环境启动之后,master和node都会将自身的信息存储到etcd数据库中 一个nginx服务的安装请求会首先被发送到master节点的apiServer组件 apiServer组件会调用scheduler组件来决定到底…

【强化学习】05 —— 基于无模型的强化学习(Prediction)

文章目录 简介蒙特卡洛算法时序差分方法Example1 MC和TD的对比偏差(Bias)/方差(Variance)的权衡Example2 Random WalkExample3 AB 反向传播(backup)Monte-Carlo BackupTemporal-Difference BackupDynamic Programming Backup Boot…

请求转发与请求作用域

创建input.jsp页面,通过表单输入学号、姓名后,单击登录按钮,控制转发到FirstServlet对其进行处理,然后通过请求对象的getRequestDispartcher()获得RequestDispartcher对象,将请求转发至SecondServlet,在Sec…

SpringBoot 可以同时处理多少请求

一、前言 首先,在Spring Boot应用中,我们可以使用 Tomcat、Jetty、Undertow 等嵌入式 Web 服务器作为应用程序的运行容器。这些服务器都支持并发请求处理的能力。另外,Spring Boot 还提供了一些配置参数,可以对 Web 服务器进行调…

北大硕士7年嵌入式学习经验分享

阶段 1 大一到大三这个阶段我与大多数学生相同: 学习本专业知识(EE专业),学习嵌入式软件开发需要的计算机课程(汇编原理,计算机组成原理,操作系统,C语言等)&#xff0c…

常见web信息泄露

一、源码(备份文件)泄露 1、git泄露 Git是一个开源的分布式版本控制系统,在执行git init初始化目录的时候,会在当前目录下自动创建一个.git目录,用来记录代码的变更记录等。发布代码的时候,如果没有把.git这个目录删除&#xff…

SpringBoot 中使用JPA

最近忙里偷闲,想写一点关于JPA的东西,另外也加深下对JPA的理解,才有了此篇博文。 一、JPA JPA (Java Persistence API)Java持久化API,是一套Sun公司Java官方制定的ORM 规范(sun公司并没有实现…

mfc140u.dll是什么文件?mfc140u放在哪个文件夹?详细修复教程

今天我想和大家分享一个非常常见的问题——mfc140u.dll丢失的困扰以及解决方法。 首先,让我们来了解一下什么是mfc140u.dll。这是一个非常重要的动态链接库文件,它是Microsoft Foundation Class Library的一个组件。许多软件和游戏都需要这个文件的支持才…

github搜索技巧

指定语言 language:java 比如我要找用java写的含有blog的内容 搜索项目名称包含关键词的内容 vue in:name 其他如项目描述跟项目文档,如下 组合使用 vue in:name,description,readme 根据Star 或者fork的数量来查找 总结 springboot vue stars:>1000 p…

(三)激光线扫描-中心线提取

光条纹中心提取算法是决定线结构光三维重建精度以及光条纹轮廓定位准确性的重要因素。 1. 光条的高斯分布 激光线条和打手电筒一样,中间最亮,越像周围延申,光强越弱,这个规则符合高斯分布,如下图。 2. 传统光条纹中心提取算法 传统的光条纹中心提取算法有 灰度重心法、…

漏洞扫描环境:win10系统用VMware Workstation打开虚拟机若干问题

win10系统用VMware Workstation打开虚拟机若干问题 一 .VMware打开虚拟机就蓝屏重启怎么解决?一. VMware打开虚拟机就蓝屏重启怎么解决?方法一:1、同时按下CTRLSHIFTESC打开任务管理器功能,之后依次点击-详细信息-性能后出现下列界…