【网络协议栈】Tcp协议(上)结构的解析 和 Tcp中的滑动窗口(32位确认序号、32位序号、4位首部长度、6位标记位、16为窗口大小、16位紧急指针)

绪论​
没有那么多天赋异禀,优秀的人总是努力翻山越岭。”本章主要讲到了再五层网络协议从上到下的第二层传输层中使用非常广泛的Tcp协议他的协议字段结构,通过这些字段去认识其Tcp协议运行的原理底层逻辑和基础。后面将会再写一篇Tcp到底是通过什么调高运行效率的,敬请期待!
请添加图片描述
话不多说安全带系好,发车啦(建议电脑观看)。

TCP协议字段

TCP协议段格式:
此处只需要对里面的字段内容有个印象,下面将会对这些字段进行逐渐解析。
在这里插入图片描述
将Tcp协议结构化,在代码中tcp协议结构:
在这里插入图片描述

tcp的数据发送模式:

  1. 串行发送:
    在这里插入图片描述
  2. 并行发送数据:
    在这里插入图片描述
    对于上面这种方法:server收到的报文顺序可能是乱序的(因为在网络中传输不能确定到达的先后顺序)

为保证按序到达就有了:

1. 32位序号:

接收方就可以根据报头中的序号,排序组合(每个报文都是带有自己的序号的!)

返回的确认信息也需要有序号,也就是报头中的

2. 32位确认序号

它一般设置成对应的32位序号+1
作用:

  1. 通过确认序号告诉用户已经收到了那些数据(返回应答是填写确认序号),它也能判断那些报文丢失。
  2. 通过确认序号也能知道返回到那个具体位置
    (先记住即可后面还会再底层讲解)

在这里插入图片描述
都是表示报文的序号,为何要把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:

  1. recv参数flag为0时默认为阻塞式读取常规数据
  2. 选项为MSG_OOB时就是收到接收紧急数据(又称带外数据:正常通信外的数据)选项。

应用场景:需要加急处理的情况

  1. 终止或暂停上传行为
  2. 服务器的检测管理

7. 16位窗口大小

用来进行流量控制的字段

  1. 发送条件不满足,发送方就会写满了发送缓冲区,进程就要阻塞。
  2. 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的确认序号是否完整:
在这里插入图片描述


本章完。预知后事如何,暂听下回分解。

如果有任何问题欢迎讨论哈!

如果觉得这篇文章对你有所帮助的话点点赞吧!

持续更新大量计算机网络细致内容,早关注不迷路。

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

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

相关文章

【保姆级】Spring Retry 教程

什么是“重试”?为什么要进行“重试”呢? “重试”(Retry)是一种在编程和软件开发中常见的策略,用于处理在执行操作时可能遇到的临时性错误或异常。当一个操作因为某些原因(如网络问题、服务不可用、资源暂时不可用等)失败时,重试机制会尝试再次执行该操作,以期在下一…

PHP发票验真 API-发票真伪查验、验证接口示例

发票验真API是一种在线服务,它允许用户或企业通过编程接口(API)验证发票的真实性。这种服务通常由政府机构或者授权的第三方(如翔云、百度)提供,旨在打击伪造发票的行为,保护消费者的合法权益&a…

JAVA-石头迷阵小游戏

采用企业式项目结构,接下来我将分享全部代码和结构,希望大家点点关注! 这是我的结构。首先使用IDE创建一个Module,命名stone-maze,接着把自带src下的main方法删除,接着在src下创建包,包名为com.wmuj,接着创建APP类代码如下: package com.wmuj;public class App {publ…

《探索 Python 音频利器:sounddevice》

一、sounddevice 简介 Sounddevice 是一个强大的 Python 音频处理库,它为开发者提供了对 PortAudio 库的 Python 绑定,从而实现了在 Python 环境中播放和录制音频数据的功能。 这个库具有诸多优势。首先,它具有跨平台性,无论是在…

进程间通信大总结Linux

目录 进程间通信介绍 进程间通信目的 进程间通信发展 进程间通信分类 管道 System V IPC POSIX IPC 管道 什么是管道 匿名管道 用fork来共享管道原理 站在文件描述符角度-深度理解管道 管道读写规则 管道特点 命名管道 创建一个命名管道 匿名管道与命名管道的区…

RabbitMQ系列学习笔记(八)--发布订阅模式

文章目录 一、发布订阅模式原理二、发布订阅模式实战1、消费者代码2、生产者代码3、查看运行结果 本文参考: 尚硅谷RabbitMQ教程丨快速掌握MQ消息中间件rabbitmq RabbitMQ 详解 Centos7环境安装Erlang、RabbitMQ详细过程(配图) 一、发布订阅模式原理 在开发过程中&…

linux查看系统类型

要确定系统是 Ubuntu 还是 CentOS,可以通过查看系统的发行版信息来判断。以下是几种常见的方法: 方法一:使用 cat 命令查看 /etc/os-release 文件 这个文件包含了系统的详细信息,包括发行版名称和版本号。 cat /etc/os-release…

ESP32-C3实现非易失变量(Arduino IDE )

1效果 网页输入数据&#xff0c;串口打印数据。掉电后数据还在 2源码 #include <WiFi.h> // 包含WiFi库&#xff0c;用于处理WiFi连接 #include <WebServer.h> // 包含WebServer库&#xff0c;用于创建Web服务器 #include <Preferences.h> // 包含Prefere…

告别微信封号!学会这5招,让你的账号坚不可摧

在这个信息爆炸的时代&#xff0c;无论是工作沟通、社交互动还是获取信息&#xff0c;微信都扮演着极其重要的角色。但是&#xff0c;随着微信平台规则的日益严格&#xff0c;账号被封的风险也随之增加。今天&#xff0c;我们就来聊聊如何有效防止 微信被封&#xff0c;让你的账…

【MySQL】入门篇—基本数据类型:NULL值的概念

在关系数据库中&#xff0c;NULL值是一个特殊的标记&#xff0c;表示缺失或未知的值。 NULL并不等同于零&#xff08;0&#xff09;或空字符串&#xff08;&#xff09;&#xff0c;它表示一个字段没有任何值。 这一概念在数据库设计和数据管理中至关重要&#xff0c;因为它影…

力扣——环形链表问题

判断链表是否有环以及入环的第一个节点 前言判断链表是否有环找到入环的第一个节点 前言 大家好&#xff0c;前段时间&#xff0c;熊二学习了关于环形链表相关的问题&#xff0c;以下是我的见解&#xff0c;希望能够帮助你们呀&#xff01; 判断链表是否有环 给定一个链表&am…

如何在一个月内快速学习掌握大模型

原本给自己的是一个月时间&#xff0c;通过梳理之后我自信的认为不需要一个月&#xff0c;两周即可&#xff0c;相较于其他技术&#xff0c;大模型应用的门槛要低得多。 先明确你想要深入到哪一层 1、基础设施层&#xff1a;了解即可&#xff0c;关注NVIDIA和超大规模厂商的最…

[自动化测试:Selenium]:环境部署和Webdriver的使用

文章目录 修改安装源打开Python Packages。点击梅花按钮。在弹出的对话框中&#xff0c;填入Name&#xff08;随便填&#xff09;&#xff0c;Repository URL&#xff0c;选择下列的源&#xff0c;一般先选择清华源按OK确认。配置完成 安装seleniumFile→Settings→Project&…

多签机制简明理解及实例说明

目录 Multisignature机制简明理解及实例说明 Multisignature机制中的公钥、私钥、Nonce及签名验签详解 加密货币托管账户的多重签名机制 Multisignature机制简明理解及实例说明 一、基本概念 Multisignature(多重签名)机制是一种先进的加密技术,它允许一笔交易必须由多…

word删除空白页 | 亲测有效

想要删掉word里面的末尾空白页&#xff0c;但是按了delete之后也没有用 找了很久找到了以下亲测有效的方法 1. 通过鼠标右键在要删除的空白页面处显示段落标记 2. 在字号输入01&#xff0c;按ENTER&#xff08;回车键&#xff09; 3.成功删除了&#xff01;&#xff01; PS…

【ArcGIS Pro实操第八期】绘制WRF三层嵌套区域

【ArcGIS Pro实操第八期】绘制WRF三层嵌套区域 数据准备ArcGIS Pro绘制WRF三层嵌套区域Map-绘制三层嵌套区域更改ArcMap地图的默认显示方向指定数据框范围 Map绘制研究区Layout-布局出图 参考 本博客基于ArcGIS Pro绘制WRF三层嵌套区域&#xff0c;具体实现图形参考下图&#x…

两性离子水凝胶助力微针传感器:稳定灵敏的监测神器

大家好&#xff01;今天我要向大家介绍一项关于生物相容性核壳微针传感器的研究——《Biocompatible Core–Shell Microneedle Sensor Filled with Zwitterionic Polymer Hydrogel for Rapid Continuous Transdermal Monitoring》发表于《ACS Nano》&#xff0c;该传感器填充两…

力扣每日打卡挑战 3184. 构成整天的下标对数目 I

给你一个整数数组 hours&#xff0c;表示以 小时 为单位的时间&#xff0c;返回一个整数&#xff0c;表示满足 i < j 且 hours[i] hours[j] 构成 整天 的下标对 i, j 的数目。 整天 定义为时间持续时间是 24 小时的 整数倍 。 例如&#xff0c;1 天是 24 小时&#xff0c…

深入解析 Golang 并发编程中的同步机制:WaitGroup 与 Mutex 详解

文章目录 一、简介二、WaitGroup 的使用1. 什么是 WaitGroup&#xff1f;2. 基本操作3. WaitGroup 示例4. 注意事项 三、Mutex 的使用1. 什么是 Mutex&#xff1f;2. 基本操作3. Mutex 示例 四、竞争条件示例与解决1. 竞争条件问题示例2. 使用 Mutex 解决竞争条件 五、使用 RWM…

FFMPEG录屏(19)--- 枚举Windows下的屏幕列表,并获取名称、缩略图

在Windows下枚举显示器列表并获取名称、缩略图 在Windows系统中&#xff0c;枚举显示器列表并获取它们的名称和缩略图是一个常见的需求。本文将详细介绍如何实现这一功能&#xff0c;涉及到的主要技术包括Windows API和C编程。 获取显示器信息 首先&#xff0c;我们需要一个…