【网络协议栈】Tcp协议(上)结构的解析 和 Tcp中的滑动窗口(32位确认序号、32位序号、4位首部长度、6位标记位、16为窗口大小、16位紧急指针)
绪论
“没有那么多天赋异禀,优秀的人总是努力翻山越岭。”本章主要讲到了再五层网络协议从上到下的第二层传输层中使用非常广泛的Tcp协议他的协议字段结构,通过这些字段去认识其Tcp协议运行的原理底层逻辑和基础。后面将会再写一篇Tcp到底是通过什么调高运行效率的,敬请期待!
话不多说安全带系好,发车啦(建议电脑观看)。
TCP协议字段
TCP协议段格式:
此处只需要对里面的字段内容有个印象,下面将会对这些字段进行逐渐解析。
将Tcp协议结构化,在代码中tcp协议结构:
tcp的数据发送模式:
- 串行发送:
- 并行发送数据:
对于上面这种方法:server收到的报文顺序可能是乱序的(因为在网络中传输不能确定到达的先后顺序)
为保证按序到达就有了:
1. 32位序号:
接收方就可以根据报头中的序号,排序组合(每个报文都是带有自己的序号的!)
而返回的确认信息也需要有序号,也就是报头中的
2. 32位确认序号
它一般设置成对应的32位序号+1
作用:
- 通过确认序号告诉用户已经收到了那些数据(返回应答是填写确认序号),它也能判断那些报文丢失。
- 通过确认序号也能知道返回到那个具体位置
(先记住即可后面还会再底层讲解)
都是表示报文的序号,为何要把32位序号和32位确认序号分开
因为这样就能实现捎带通信,也就是Server将应答和信息存放到一起发送给Client客户端
再所以因为他既是数据又是应答,所以就需要有两个序号来分别代表数据和应答
也就有了:
捎带应答
捎带应答就是通过序列号和确认序列号实现把数据和应答合并成一个报文进行发送
用括号圈起来的(ACK和信息) 他们直接通过同一个tcp报文就发送回来了
总结:tcp保证可靠性但不仅仅保证可靠性,为了进行可靠性的同时还要提高效率(并行发送、捎带应答)
3. 4位首部长度
四位首部长度的单位是:4byte
又因为有4位所以换成10进制长度就有16个也就是:[0,15] 再 * 4(基本单位) ,得到tcp报文最长为60 byte
通过他确定就能确定有效载荷的长度,当得到报文长度再减去报头前的固定长度(20byte) 就得到了有 效载荷(数据的长度)的最长长度40byte
如果tcp长度是20,报头固定长度20byte(也表明没有有效载荷)
如果tcp长度是40,报头固定长度20byte,有效载荷数据就是20byte
报头有效载荷的分离是通过4位首部长度进行把报头和有效载荷区分出来,再将有效载荷向上交付是通过存的源和目的端口号来找到对应所需数据的软件位置。
当Client发送大量数据,但Server读取不够快就会导致接收缓冲区被填满(当装满后装不下的数据将会被丢弃!)
所以若接收方来不及接收了,发送方就不要再发送了,就需要进行流量控制(OS控制tcp协议来完成,传输控制协议(流量控制…))
如何进行流量控制:发送方就需要得知接收方的接受能力(接收缓冲区的大小)
4. 6位标记位
serve在接收信息时,一定会收到各种各样的不同类型的tcp报文
所以对于不同的报文就需要有不同的类型进行区分和分别的使用!
所以才有各种标记位
例:ACK就是应答类型的报文!
具体的标记位:
1.ACK:确认报文接收到了
2. SYN:握手请求(建立链接)
3. URG:紧急报文(不在通过序号进行排序)
4. PSH:push推送,告诉对方,尽快进行把数据向上交付(指令服务)
5. RST:reset重置,连接重置
虽然说tcp可靠的,但并不是说保证发送数据100%成功,而是数据发送出现问题了/发送成功了/发送失败了自身知道,并提供解决方案。
RST使用的例子:
上图含义:在tcp三次握手中若第三次握手的ACK丢失后,客户是无法得知的因为客户认为的是只要把ACK报文发送过去就握手完成建立链接了,所以此时本质是没有链接上的,当客户发送信息给服务器时,服务器就会告知客户端并没有链接成功(也就是会发送设置了RST标记位的报文),这就是发送RST的情况,也就是所谓的链接不一致,需要重置连接。
tcp的三次握手就是赌最后一个报文对方收到了,也就表明了tcp的三次握手是不一定成功的!!
6. 16位紧急指针
它代表的是:需要紧急处理的数据在有效载荷中的偏移量
这样就能优先找到需要紧急处理的数据,并且紧急数据的大小只能是一个字节
处理紧急指针的方法:
当使用recv函数时对flags字段进行设置MSG_OOB:
- recv参数flag为0时默认为阻塞式读取常规数据
- 选项为MSG_OOB时就是收到接收紧急数据(又称带外数据:正常通信外的数据)选项。
应用场景:需要加急处理的情况
- 终止或暂停上传行为
- 服务器的检测管理
7. 16位窗口大小
用来进行流量控制的字段
- 发送条件不满足,发送方就会写满了发送缓冲区,进程就要阻塞。
- 16位窗口大小,OS就会填写接收方TCP协议字段中的接收缓冲区剩余的空间大小,然后返回给发送方,这样发送方就知道接收方的接收能力,接收方就会只会发送小于16位窗口大小的数据。
如何确定接收方接收到消息:
当发送消息后,接收方会返回一条接收成功 应答消息 这样只要收到应答就能100%保证历史最近一条数据被对方收到(确认应答!)
Tcp滑动窗口:
tcp的起始序号:起始序号是由tcp协议进行随机生成的
序号 = 起始序号 + 真实序号
附:在tcp通信之前,会进行三次握手交换tcp报头,在这过程中随机序号双方也就能协商好。
使用随机序号就能减少历史报文、以及黑客入侵的影响。
滑动窗口过程:
既然这样一发一收的方式性能较低, 那么我们一次发送多条数据, 就可以大大的提高性能(其实是将多个段的等待时间重叠在一起了).
并发大量暂时用不到的ACK的数据段进行提前预留,当要使用时就能直接使用减少发送间所需的时间,从而提高效率的解决方案
收到第一个ACK后(应答), 滑动窗口向后移动, 继续发送第五个段的数据; 依次类推。
操作系统内核为了维护这个滑动窗口,需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答; 只有确认应答过的数据, 才能从缓冲区删掉。
具体如下图:
上图白色窗口就是所要发的数据,可以把它理解为一个队列当数据输出后另外一个数据进来,也就是往右移的过程
而移动的本质其实也就是数组中指针(数组下标)的移动。
滑动窗口的大小:
由对方的接收能力决定(后面会讲 其实是对方的接收缓冲区16为窗口大小的大小和当前网络的拥塞窗口大小决定)
滑动窗口如何更新:
通过接收方返回win_start(开始放数据的位置下标值) 和 win滑动窗口的大小(接收方设定返回)
1. win_start = 确认序号(序号 + 1)
2. win_end = win_start + win(偏移量)
最开始每发送数据第一次滑动窗口的大小:同样是在三次握手期间协商的!
滑动窗口是会变小的,当只进行确认数据,而不取数据时,这样滑动窗口内的接收能力就会不断变小。
因为win_start是不断右移,而因为用户没有读取数据(返回win = 0),win_end指针就不会移动,所以win值就会变小
所以滑动窗口也是会变成0的,同理当win_start移动到win_end处是win就是0
滑动窗口也是能变大的,用户当把收到数据都获取(就有空间了就修改win),这样窗口就会扩大接收能力,这样的话win_end就会右移,从而让win窗口变大会,变成协商好的原窗口的大小。
窗口探测机制:
上述滑动窗口的变化也就是流量控制的解决方案:
1. 接收方接收能力弱时:发送慢
2. 接收能接收能力强时:发送快
接收端如何把窗口大小告诉发送端呢?
回忆我们的TCP首部中, 有一个16位窗口字段, 它就是存放了窗口大小信息
那么问题来了, 16位数字最大表示65535, 那么TCP窗口最大就是65535字节么? 实际上, TCP首部40字节选项中还包含了一个窗口扩大因子M, 实际窗口大小是 窗口字段的值左移 M 位;
会不会滑动到越界:
其实发送缓冲区设计成环形结构(因为前面已经发送的数据其实是可以被覆盖的!)
附:
确认序号的序号代表着该序号之前的数据全部收到了
滑动窗口的报文丢失了怎么办?
当发送的报文丢失时:
通过查看ACK的确认序号是否完整:
本章完。预知后事如何,暂听下回分解。
如果有任何问题欢迎讨论哈!
如果觉得这篇文章对你有所帮助的话点点赞吧!
持续更新大量计算机网络细致内容,早关注不迷路。
相关文章:

【网络协议栈】Tcp协议(上)结构的解析 和 Tcp中的滑动窗口(32位确认序号、32位序号、4位首部长度、6位标记位、16为窗口大小、16位紧急指针)
绪论 “没有那么多天赋异禀,优秀的人总是努力翻山越岭。”本章主要讲到了再五层网络协议从上到下的第二层传输层中使用非常广泛的Tcp协议他的协议字段结构,通过这些字段去认识其Tcp协议运行的原理底层逻辑和基础。后面将会再写一篇Tcp到底是通过什么调…...

手表玻璃盖板视觉贴合
在手表生产过程中,贴合加工是一个至关重要的环节,它涉及将手表的盖板与LCM模组或各种功能片进行精准贴合。这一过程不仅要求高度的精度,还追求效率与稳定性,以满足现代可穿戴设备日益增长的市场需求。然而,当前行业在这…...

电信和互联网行业数据安全评估师CCRC-DSA人才强基计划
“电信和互联网行业数据安全人才强基计划”(以下简称“强基计划”)自 2022 年 4 月启动伊始,始终秉持以人才需求为导向,以体系化能力建设为重点,扎实铸就数据安全人才培养品牌,力促行业数据安全人才培养工作…...

MQTTnet 4.3.7.1207 (最新版)使用体验,做成在线客服聊天功能,实现Cefsharp的物联的功能(如远程打开新网址)
一、MQTTnet 4.3.x版本客户端 将客户端集成到 cefsharp 定制浏览器中,实现物联网功能 网上很多代码是3.x版本代码,和4.x版本差异性较大,介绍较为简单或不系统 二、部分代码说明 初始化,初始化》连接服务端》发布上线信息(遗嘱)ConnectAsync等 订阅主题:SubscribeAsync 接…...

将java项目jar包打包成exe服务
1.结构展示 2.注意事项 前提: 环境准备:jdk8 和 .net支持 { 1.控制面板》程序和功能》启用和关闭windows功能》.net的勾选》2.jdk8自行百度安装环境3.其他项目必须的软件环境安装等(数据库...) }第一次准备: 1.将打包好的jar包放到premiumServices.exe…...

Django请求响应对象
在 Django 中,请求(request)和响应(response)对象是处理 HTTP 请求和返回 HTTP 响应的核心。它们分别由 Django 的 HttpRequest 和 HttpResponse 类表示。 HttpRequest 对象 HttpRequest 对象包含了客户端发送的所有…...

DevExpress中文教程 - 如何在静态SSR模式下使用Blazor Drawer组件?
Microsoft的 .NET 8 UI框架引入了静态服务器端呈现模式(静态SSR)——组件在服务器端呈现,然后返回到客户端,没有任何交互,DevExpress Blazor Drawer组件需要交互式呈现模式来动态地改变其IsOpen状态。 在本文中&#…...

商汤科技十周年公布新战略,将无缝集成算力、模型及应用
10月18日,恰逢商汤科技十周年庆典,“2024商汤十周年国际论坛:迈向AI 2.0共融新时代”在香港科学园成功举办。 据「TMT星球」了解,来自全球的行业领袖、政府代表、AI专家共聚于此,共同探讨AI行业的未来。 活动上&…...

【如何获取股票数据07】Python、Java等多种主流语言实例演示获取股票行情api接口之沪深A股历史分时MA数据获取实例演示及接口API说明文档
最最近一两年内,股票量化分析逐渐成为热门话题。而从事这一领域工作的第一步,就是获取全面且准确的股票数据。因为无论是实时交易数据、历史交易记录、财务数据还是基本面信息,这些数据都是我们进行量化分析时不可或缺的宝贵资源。我们的主要…...

Rust语法基础
注释 所有的开发者都在努力使他们的代码容易理解,但有时需要额外的解释。在这种情况下,开发者在他们的源码中留下注释,编译器将会忽略掉这些内容,但阅读源码的人可能会发现有用。 和大多数的编程语言一样,主要有一下两种: 单行注释 // 多行注释 /* */ 基本数据类型 Ru…...

AWS WAF实现API安全防护
在当今的互联网环境中,API安全防护变得越来越重要。本文将介绍如何使用AWS WAF(Web Application Firewall)来实现有效的API安全防护策略。 背景 我们有一个API服务,其URL模式如下: https://dev.example.com/bff-app/sec/v1/module-a/feature-a/sub-feature-a我们需要使用AWS…...

vue将table转换为pdf导出
安装依赖: 首先,你需要安装 jspdf 和 html2canvas 这两个库。 npm install jspdf html2canvas创建Vue组件: 创建一个Vue组件,用于显示表格并提供导出PDF的功能。 <template> <div> <div id"table-contain…...

20240818 字节跳动 笔试
文章目录 1、编程题1.11.21.31.4岗位:BSP驱动开发工程师-OS 题型:4 道编程题 1、编程题 1.1 小红的三消游戏: 小红在玩一个三消游戏,游戏中 n 个球排成一排,每个球都有一个颜色。若有 3 个颜色相同的球连在一起,则消除这 3 个球,然后剩下的球会重新连在一起。在没有 …...

在Debian上安装向日葵
说明: 因为之前服务器上安装了 PVE (Proxmox VE),之前是用 Proxmox VE 进行服务器资源管理的。出于某些原因,现在不再通过 PVE构建的虚拟机来使用计算资源,而是通过 PVE 自带的 Debian 系统直接使用虚拟机资源(因为积…...

13.2 Linux_网络编程_UNIX域套接字
概述 什么是UNIX域套接字: UNIX域套接字是使用套接字进行本地通信,TCP/UDP是使用套接字进行网络通信。UNIX域套接字也有域流式套接字和域数据报套接字,这两种形式域TCP/UDP的含义类似,使用步骤也完全一致。 bind时绑定的结构体…...

10.22 多进程间通信-共享内存、信号量集
练习:通过信号量集完成对共享内存的同步操作 案例代码: 分文件编译:信号量集部分 sem.h #ifndef __SEM_H__ #define __SEM_H__ #include <myhead.h> union semun {int val; /* Value for SETVAL */struct semid_ds…...

输入输出管理器的使用
解释 InputMgr 是一个输入管理器,主要用于检测并管理用户的输入事件(例如键盘和鼠标输入)。它通过监听输入事件,并利用事件中心 (EventCenter) 来触发相应的事件。在这里,你可以管理多种输入类型,如按下、…...

windows连接linux服务器上的jupyter lab
文章目录 服务器上开启jupyter lab本地cmd将端口8888映射到服务器的8889上本地浏览器打开8888端口 服务器上开启jupyter lab jupyter-lab --ip 0.0.0.0 --port 8889 --no-browser --allow-root本地cmd将端口8888映射到服务器的8889上 ssh -N -f -L localhost:8888:localhost:…...

golang生成并分析cpu prof文件
1. 定义一个接口,请求接口时,生成cpu.prof文件 在主协程中新启一个协程,当请求接口时,生成一个60秒的cpu.prof文件 go func() {http.HandleFunc("/prof", startProfileHandler)http.ListenAndServe(":9092"…...

【Python爬虫实战】XPath与lxml实现高效XML/HTML数据解析
🌈个人主页:https://blog.csdn.net/2401_86688088?typeblog 🔥 系列专栏:https://blog.csdn.net/2401_86688088/category_12797772.html 目录 前言 一、为什么学习xpath和lxml (一)高效解析和提取数据 …...

软件测试学习笔记丨Selenium学习笔记:元素定位与操作
本文转自测试人社区,原文链接:https://ceshiren.com/t/topic/22510 本文为霍格沃兹测试开发学社的学习经历分享,写出来分享给大家,希望有志同道合的小伙伴可以一起交流技术,一起进步~ 说明:本篇博客基于sel…...

在 HTML 中,<input> 元素支持的事件汇总
在 HTML 中,<input> 元素支持多种事件,这些事件可以在用户与输入字段交互时触发。以下是一些常见的 <input> 事件: input: 当 <input> 元素的值发生变化时触发。适用于文本、数字、日期等类型的输入。 change: 当 <inp…...

vue3【实战】 渲染 md 文件(markdown语法 .md后缀的文件)
1. 安装相关插件 npm i unplugin-vue-markdown markdown-it-prism prism unhead/vue2. 添加配置 src/main.ts // 给 md 文件创建头部 import { createHead } from unhead/vue // md 文件中代码高亮的样式 import prismjs/themes/prism.css // 自定义 md 文件的样式 import /as…...

Sora高端制造业WordPress外贸主题
Sora是一款专为高端制造业设计的WordPress主题,由国内知名wordpress开发团队简站wordpress主题开发,它以红色为主色调,适合外贸企业出海建独立站的模板。这个主题适用于WordPress 6.0及以上版本,并且只服务于真正有需要的用户。主…...

windows安装superset及各种问题解决
1,背景 先说说背景,之前在2月份已经安装过superset3.1.1,当时还没有提示SECRET_KEY异常,能正常运行,且已配置数据库连接. 2,报错信息及解决途径 1,创建admin时,提示Error! User already exists 这个是因为之前已经创建过admin用户,需要删除C:\Users\用户名\.superset下的.…...

JMeter模拟并发请求
PostMan不是严格意义上的并发请求工具,实际是串行的,如果需要测试后台接口并发时程序的准确性,建议采用JMeter工具。 案例:JMeter设置20个并发卖票请求,查看后台是否存在超卖的情况 方式一:一共10张票&…...

【小趴菜前端实习日记5】
实习日记5 一、vue3中如何使用router(获取this)二、ts中用object定义类型太宽泛导致Ts无法推断出正确类型三、动态设置日记封面失败vite动态引入静态资源1.方法一vue3父子组件生命周期执行顺序 2.方法二3.方法三 四、打包问题总结1.The import.meta meta-property i…...

如何通过谷歌外推占据搜索引擎首页?
外贸企业在推广过程中,如何在谷歌搜索引擎中占据有利位置,获取更多曝光,GLB谷歌霸屏服务就可以派上用场。它通过高效的品牌外推策略,可以让你的企业信息在谷歌中实现“霸屏”效果,特别是长尾关键词的全面覆盖 很多企业…...

jmeter学习(6)逻辑控制器
1. 简单控制器 简单控制器用来存放组件的,没有提供什么逻辑功能。 2. 循环控制器 用来循环执行请求,可以配置循环次数。注意它与线程组、测试计划中的循环是相互独立的,比如在线程组中设置循环2次,循环控制器设置循环3次&#…...

Android14 和android12 在锁屏界面Keyguard输错5次密码后倒计时30秒时重启手机不显示倒计时
参考如下修改:Android9.0在锁屏界面Keyguard输错5次密码后倒计时30秒时重启手机不显示倒计时_android 锁屏密码输错5次-CSDN博客 android 14 修改如下: androidap/SYSTEM/frameworks/base$ git status Refresh index: 100% (47218/47218), done. HEAD d…...