【计算机网络】TCP报文详解

认识TCP报头

其实协议的形式都是一个结构化的数据,TCP协议也不例外。一起来看看TCP协议的报头是怎么样的。

在这里插入图片描述

以上就是TCP报头,实际上是一个结构化的数据,也就是一个结构体。例如:

struct tcp_hdr
{unsigned int stc_port : 16;unsigned int desc_port : 16; unsigned int seq;unsigned int ack_seq;....
};

目的端口号&&源端口号

其中16位源端口号,就是你当前发送报文的端口号。目的端口号则是目标主机的端口号。

这也就是我们在用accept时,能够获取连接套接字的同时,还能获取到对端主机的端口号(ip也获取到了,这个在网络层的时候解释)。 而目的端口号也很好理解,因为端口号能够确定一台主机中唯一的一个进程。当你的报文被发送到对端主机的时候,就能够通过端口号去锁定对应的PCB进程。

4位首部长度

4位首部长度代表的是报头占多少大小,这回有人问了,4位不是 0000 - 1111 ,也就是 0 -15这个区间吗?

可是报头的基本大小都20了。 实际上上,4位首部长度 * 4 才等于报头的实际大小。也就 0 - 60区间,报文长度默认是20字节,也就说明4位首部长度默认为5。

如何解包&&分用?

如何解包

还记得我们上面提到的4位首部长度吗? 当TCP层收到TCP报文时,会先提取前20个字节。获得除了选项以外,报文的其他信息。随后再去查看4位首部长度,如果4位首部长度 * 4 大于20 。那么再减去20个字节,把剩余的字节提取出来,那么剩下的不就是我们TCP报文的有效载荷吗?

在这里插入图片描述

如何分用?

还记得我们报头上有个目的端口号字段吗?在操作系统里,会存在一张hash表,而port则是对应的key值,value值就是我们的进程PCB。所以操作系统可以通过报文中的目的端口号,去找到该端口号绑定的进程PCB。

在这里插入图片描述

找到了进程的PCB之后,PCB内部又有一个files_struct的结构体,里面有fd_arr[]数组,数组存储的是描述文件结构体的指针*file,数组的下标则是对应的文件描述符fd。而此时操作系统会创建一个新的文件,这个新的文件的下标就是我们经常见到的sock。而此时传输层并不知道sock是多少,但是当我们进行read的时候,会把sock传进去。此时传输层就知道了sock是多少,并找到PCB中sock对应的文件。把数据拷贝到该文的缓冲区。

在这里插入图片描述

这其中还有很多细节,不过我们大致知道一个流程就行了。所以,数据是通过TCP层拷贝到sock套接字的文件缓冲区的!那么这也意味着,TCP内部也是有缓冲区的! 因为客户什么时候从TCP上读取数据是不确定的!这就意味着TCP必须要有保存数据的能力!

TCP的可靠性

为什么网络传输的时候,会存在不可靠的问题?

很简单,因为距离太远!就好比你和你的室友说话,离的越近他听到的就越清除。如果你和他隔了50米说话,人家还能听清吗?人家听不清甚至听不到!这就是你发送的信息丢失了!而在网络中也一样,随着距离的变长,数据丢失的可能就越大。如果数据丢失了,那么我们是不是要采取相对应的策略。去解决这些问题呢?而解决这些问题就提高了可靠性。

不可靠问题常见的有哪些不可靠的场景?

1. 丢包

顾名思义,你的报文丢失了。也就是你的数据丢失了,这是一种不可靠的场景。

2. 乱序

这个也很好理解,比如你发送了5个报文,分别是以 1, 2 ,3 ,4 ,5的顺序发送的,可是对端接收却以5,2,3,4,1接收的。就好比你和你女神发:你喜欢我不。 结果你女神那边却收到:我不喜欢你。这样你的爱情直接毁于一旦了,所以肯定是不可靠的。

3. 校验错误

就是检查你的报文有没有不合理的地方。

4. 重复

你发送了一条报文,但是你以为对方没收到,然后发送了多条报文。但是对方其实都收到了,就说明你发送了重复的报文,这也是不可靠的一种场景

当然,不可靠的场景还有很多,这里就不一 一细说了。

确认应答机制

抛出一个问题:如果距离长了,存不存在绝对的可靠性?

先说结论,答案是不存在!

为什么呢?

就好比我们的A 和 B 说话,他俩之间隔了500米。A 对 B 说,你吃饭了吗?

在这里插入图片描述

这时候B收到了消息,但是A并不知道B有没有收到消息。所以这时候B回了一句: 吃了!

在这里插入图片描述

当A收到"吃了"这条消息的说话,A 可以肯定的是,他的上一条消息 "你吃饭了吗?"是被对方收到了的!但此时B并不知道A是否收到自己发送的消息。所以此时A又进行了回复。

在这里插入图片描述

A向B发送"吃的什么呀?",此时B也知道,他的上一条消息"吃了"是被A接收到了的!但此时A也并不知道自己新发的消息"吃的什么呀?"是否被B接收到。

再举个例子,你在宿舍叫你的室友。但是他没有一点反应,这就是你没有收到应答,你没有收到应答,是不是你就会认为他没听见?你会认为你的消息丢包了。所以你会再叫一遍。这时候他听到了,点了点头,或者看了你一眼,或者和你说话。这些都是对方听到你消息的一种应答。

通过上面的例子,我们可以得到结论:

1. 我们认为,只有收到了回复,我们才能100%确认对方收到了我们发送的历史消息

2. 双发通信,一定存在最新的数据没有应答!而最新的这一条消息无法保证可靠性!

32位序号与32位确认序号

32位序号代表TCP缓冲区的数组下标。每次发送时,都会把这个下标发给对端,当对端接收时,返回应答时,会填入32位确认序号。32位确认序号填的是这个序号之前的报文,已经全部收到了。

在这里插入图片描述

而我们都知道,如果发送发出去的顺序和对端接收的顺序不一致,也就是乱序的。那么这是不可靠的,因为有可能是客户端发送一批报文,服务器再给出一批应答。这种情况TCP是不能保证接收的时候是有序接收的,而这时候就可以通过确认序号对接收来的报文进行排序,这样交给上层时就是有序的。也就是说按什么顺序发,就按什么顺序收。

在这里插入图片描述

为什么报文不只设置一个序号?

为什么报文设置2个序号,而不是一个序号? 反正也只是确认一下。 这是因为TCP是全双工的!再保证自己接收数据的情况下也要发送数据!所以这也就意味着仅仅一个序号是不行的!

16位窗口大小

我们都知道,TCP是有缓冲区的。如果上层迟迟不拿数据,或者服务器压力太大。会导致缓冲区的数据不能及时取走,如果最后服务器的接收缓冲区已经被打满了。那么客户端是否还要发送数据呢? 如果服务器的接收缓冲区快满了,那么你的客户端发送多少数据呢?如果服务器此时的缓冲区只剩下5个字节可用了。可是你的这一个TCP报文却发送了100字节。是不是意味着有95字节,没地方放了?所以为了保证合理的传输数据,就引入了16位窗口大小的概念。

而这个16位窗口大小,就是用来告诉对端,自己的接收能力!告诉对端,自己能接收多少数据,所以16位窗口大小填的是自己的接收长度!!然后对端收到这个报文后,知道了你的接收能力!就会根据你的接收能力给你传输适合大小的数据!

在这里插入图片描述

6位标志位

我们要先明白6位标志位的意义是什么,我们都知道sock套接字再创建时都要指明它的协议类型,是udp通信还是tcp通信还是…所以我们的TCP报文也不例外,**我们的TCP报文也有类型!**而这个6位标志位就是代表着报文的类型。

在这里插入图片描述

ACK标志位(acknowledgment)

ACK是一个确认应答标志位,我们上面说过。TCP最新的一条报文是无法保证可靠性的!所以如果你收到了对方的消息,你要告诉它你收到了!你就需要把ACK标志位由0置为1。再发生给对方后,对方就知道你收到了它的报文(这里会有丢包问题,后面的文章会讲解解决策略)。

SYN标志位(synchronization)

我们都知道TCP是面向连接的,而TCP的连接规则是三次握手。当你客户端向服务器发起连接时,那么TCP报文需要把SYN标志段设置为1。这样服务器接收到你这个报文时,就知道你是想和服务器建立连接。随后服务器会返回一个SYN + ACK都被设置了的报文,证明服务器收到了你的连接请求并和你建立连接。而这个过程就是TCP三次握手过程!具体的三次握手过程以及为什么要三次握手,后面会有详细讲解。

FIN标志位(finish)

我建立连接需要SYN标志位告诉服务器,我要建立连接了!

那么我们如果要断开连接时,是不是也要告诉服务器,我要断开连接了!(直接拔电源除外…)

所以当我们断开连接时,客户端(一般由客户端主动断开连接)会向服务器发送FIN为1的标志位的报文。告诉服务器,客户端要断开连接了!随后服务器给你应答后,也会给你发送一个FIN报文。你再给服务器发送ACK确认后,那么连接就断开了,这个过程也就是四次挥手。四次挥手详细过程后面会有讲解。

URG标志位(urgent)

我们上面说了32位序号可以用来对报文排序,让报文有序的交付给上层。 但是如果有的报文想搞特殊,想插队咋办?那们只需要把TCP报文的URG标志位设置位1。这样TCP收到这个报文不会把这个报文加入排序,而是立即处理这个报文。

而这个报文需要被尽快处理的数据在哪?

TCP报文中还有一个字段,那就是16位紧急指针

这个指针存的是在有效载荷中的偏移量!

那么紧急处理的数据占多少个字节呢?答案是1个字节!而这个数据我们称之为带外数据

用到URG标志位的场景非常的少,很少会用到。 如果你想服务器立马区帮你完成某一件事,你可以用上URG标志位。带外数据设置为 0,则返回服务器的健康状态…,设置为1,则去调用一个进程…等等。

PSH标志位(push)

当对端的接收缓冲区已经满了的时候,而你这边的会定时的发送TCP报文,收到对方的应答之后去查看对方的接收能力。可是试了几次,对方还是无法接收你报文的时候。这边已经忍无可忍了,就会把PSH设置为1,去催促对端让对端把数据赶紧取走。如果你是故意不read的,那没办法,人家也拿你没办法。我们都知道read会等待条件是否就绪,如果条件不就绪就会阻塞。而当收到带有PSH被设置的报文时,就会尽快的让read的等待条件就绪,以至于让上层读取数据后恢复自己的接收能力。这样这边的数据就可以发送了。所以,PSH就是让对端的read条件尽快就绪! 具体细节和多路转接有关,后面的博客会更新多路转接相关的知识。

RST标志位(reset)

我们上面说过,当程序结束时,要断开连接。但是有人不按套路出牌,直接拔电源让电脑关机。这样就没机会发送断开连接的报文。所以就会出现一种场景,就是服务器和客户端已经建立了连接。但是服务器直接操作系统重启了,也没来得及断开连接。而此时客户端也没有给服务器发送消息。等到服务器主机重启后重新运行服务进程时,你的客户端此时还认为是和服务器建立了连接的,但此时服务器刚刚重启,不认得客户端。所以客户端给服务器发送报文时,此时的服务器就很奇怪。对端怎么直接把报文发过来了?不是要先建立连接吗? 所以此时服务器就会在应答报文上设置RST标志位。意思就是连接重置!

在这里插入图片描述

还有一种情况也会发送重置RST,那就是三次握手失败的情况!在客户端最后一次ACK没有被服务器收到的时候。客户端认为自己已经和服务器建立了连接,而服务器却认为没有和客户端建立连接。所以此时客户端直接给服务器发送数据报文,服务器也会返回重置了RST的报文应答。

在这里插入图片描述

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

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

相关文章

分布式光纤测温DTS与红外热成像系统的主要区别是什么?

分布式光纤测温DTS和红外热成像系统在应用领域和工作原理上存在显著的区别,两者具有明显的差异性。红外热成像系统适用于表现扩散式发热、面式场景以及环境条件较好的情况下。它主要用于检测物体表面的温度,并且受到镜头遮挡或灰尘等因素的影响会导致失效…

英语学习笔记35——Our village

Our village 我们的村庄 词汇 Vocabulary photograph n. 照片 通常说:photo 复数:photos     picture 复数:pictures 搭配:take a photo 照相 以o结尾的单词复数es的: potato —— potatoes tomato —— tomatoe…

Prometheus+Grafana监控MySQL

一、准备 grafana服务器:192.168.48.136Prometheus服务器:192.168.48.136被监控服务器:192.168.48.134、192.168.48.135查看时间是否同步 二、安装prometheus server 【2.1】安装 # 解压安装包 tar -zxvf prometheus-2.52.0.linux-amd64.t…

Element UI 日期组件自定义可选范围

官网地址 :Element - The worlds most popular Vue UI framework 自定义方式: 在data()函数中定义 // 日期选择器可选范围expireTimeOption: {disabledDate: time > {// 判断是否是在任务时间段if (this.isTaskRandTime(time)…

数字人直播系统源码,不需要高价购买,只需这个价!

在技术领域,系统源码的价格往往令人咋舌,尤其是涉及到高端应用如数字人直播系统时。那么,一套数字人直播系统源码到底需要多少钱?面对高昂的价格,是否还值得进入这个行业? 首先,我们要认识到数…

UE5-不同材质上脚步声

主要是用物理材质给不同的材质加一个标签 创建材质 首先去设置里面创建几个地形材质名称,我这里创建了Grass,Rock,Wood,Water (就是名字而已) 然后创建物理材质(物理材质可以添加到现有的普通…

虚拟仿真实训平台助力院校人才培养与产业发展共赢

一、虚拟仿真实训平台简单介绍 虚拟仿真实训平台适用于虚拟仿真实训教学场所,几乎兼容所有虚拟仿真实训显示设备,能够完成虚拟仿真实训资源进行跨专业、跨院校、跨地域的统筹管理。且虚仿平台具备虚拟仿真实训教学过程的监控分析及虚拟仿真实训资源集合…

WPF中的隧道路由和冒泡路由事件

文章目录 简介:一、事件最基本的用法二、理解路由事件 简介: WPF中使用路由事件升级了传统应用开发中的事件,在WPF中使用路由事件能更好的处理事件相关的逻辑,我们从这篇开始整理事件的用法和什么是直接路由,什么是冒…

探索大数据在信用评估中的独特价值

随着我国的信用体系越来越完善,信用将影响越来越多的人。现在新兴的大数据信用和传统信用,形成了互补的优势,大数据信用变得越来越重要,那大数据信用风险检测的重要性主要体现在什么地方呢?本文将详细为大家介绍一下,…

深入理解并打败C语言难关之一————指针(3)

前言: 昨天把指针最为基础的内容讲完了,并且详细说明了传值调用和传址调用的区别(这次我也是做到了每日一更,感觉有好多想写的但是没有写完),下面不多废话,下面进入本文想要说的内容 目录&#…

怎么提升机器人外呼的转化效率

在某些情况下,如市场调查、产品推广等,语音机器人可以高效地完成大量的呼叫任务,并能通过预设的语音脚本和智能识别功能,初步筛选和分类潜在客户。此时,不转人工可能更为高效和经济。 然而,在一些需要深度沟…

停止游戏中的循环扣血显示

停止游戏中循环扣血并显示的具体实现方式会依赖于你的代码结构和游戏的逻辑。通常情况下,你可以通过以下方式来实现停止循环扣血和显示: 1、问题背景 在使用 Python 代码为游戏开发一个生命值条时,遇到了一个问题。代码使用了循环来减少生命…

【PLG洞察】|向Figma学习如何打造标杆客户和实施分销策略

Figma是一款功能强大的在线协同设计工具,它主要被用于界面设计、原型设计和用户体验设计。作为国外知名的saas企业,对标国内的saas蓝海,它的增长实在惊人!据称,Figma2020年的收入已达$75M, 2021年6月,美国的…

Kafka流计算培训:打造Kafka技术专家,引领大数据未来

Kafka流计算培训课程是一门旨在帮助大数据从业人员和欲从事Kafka技术的人员快速掌握Kafka核心技术的专业培训项目。 在这个3天的课程中,我们将全面细致地讲解Kafka流计算软件的配置、Kafka流计算开发和流计算管道设计等内容,让学员能够在实际工作中灵活…

C++的异常捕获

目录 C语言的异常处理方式 C的异常处理方式 异常的抛出与捕获 抛出与捕获原则 异常安全 C语言的异常处理方式 1、终止程序 常见形式:assert 缺陷:太过强硬,如果发生内存错误,或者除0语法错误等就会直接终止程序 2、返回错误码…

2024年新闻传播、社会科学与公共艺术国际会议(ICJSSPA2024)

2024年新闻传播、社会科学与公共艺术国际会议(ICJSSPA2024) 会议简介 2024年新闻传播、社会科学与公共艺术国际会议(ICJSSPA2024)即将在上海举行。这项国际活动将汇集来自世界各地的新闻和传播学者、社会科学研究精英和公共艺术领域的创新者。会议旨在搭建一个开放包容的交…

MySQL Online DDL原理解读

Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 💥💥个人主页:奋斗的小羊 💥💥所属专栏:C语言 🚀本系列文章为个人学习…

Idea jdk配置的地方 启动时指定切换的地方

jdk 配置的地方 项目sdk 所在位置 管理添加或删除的地方,增加后,可以在在上面切换 启动时指定版本

UE4中性能优化工具合集

UE4中性能优化工具合集 简述CPUUnreal InsightUnreal ProfilerSimpleperfAndroid StudioPerfettoXCode TimeprofilerBest Practice GPUAdreno GPUMali GPUAndroid GPU Inspector (AGI) 内存堆内存分析Android StudioLoliProfilerUE5 Memory InsightsUnity Mono 内存MemreportRH…

Spring Security 与 JWT、OAuth 2.0 整合详解:构建安全可靠的认证与授权机制

Spring Security 与 OAuth 2.0 整合详解:构建安全可靠的认证与授权机制 将 JWT(JSON Web Token)与 OAuth 2.0 整合到 Spring Security 中可以为应用程序提供强大的认证和授权功能。以下是详细的整合步骤和代码示例。 1. 引入依赖 首先&am…