【计算机网络】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.mzph.cn/web/26923.shtml

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

相关文章

光储充一体化,开启绿色出行新篇章

一、追光逐梦,绿色能源点亮未来 在蔚蓝的天空下,光伏发电板如同一片片金色的叶子,静静地捕捉着太阳的光芒。它们不仅为大地带来光明,更是绿色出行的强大后盾。光储充一体化充电站,以光伏为源,储能为桥&…

Kubernetes集群部署Prometheus和Grafana

目录 一、部署Node-Exporter 二、Prometheus安装和配置 1.创建账号并予以授权 2.创建存储卷存储Prometheus配置信息 3.通过Deployment方式部署Prometheus 4.创建Service 三、Prometheus配置热加载 四、Grafana安装 五、K8s部署Kube-State-Metrics 1.创建Kube-State-M…

C#开发-集合使用和技巧(一)常用集合和方法介绍

C#开发-集合使用和技巧 &#xff08;一&#xff09;常用集合和方法介绍常用集合和方法介绍 C#开发-集合使用和技巧1. 集合基础集合介绍集合跟数组对比 2.我们常用的集合类型列表List<T>键值对集合Dictionary<TKey,TValue>队列Queue<T>其他一些集合类型堆栈St…

架构设计 - MySQL 插入数据性能优化策略

mysql 数据库提高数据插入效率主要可以考虑以下方面&#xff1a; 使用批量插入数据的 SQL 语句&#xff0c;避免使用 for 循环逐条记录插入。 所有插入语句共用一个事务&#xff0c;避免1条SQL语句开1个事务&#xff0c;所有操作都完成后再提交事务。 尽量按照索引递增顺序插入…

Apache Doris单机快速安装(已踩坑)

官方文档&#xff1a;https://doris.incubator.apache.org/zh-CN/docs/get-starting/quick-start/ 环境&#xff1a; 操作系统&#xff1a;CentOS7.6 X86_64 JDK&#xff1a;Oracle jdk1.8.0_351 1.版本下载 从 doris.apache.org 下载相应的 Doris 安装包&#xff0c;并且解压…

Springboot防疫知识科普系统-计算机毕业设计源码03531

摘 要 如今计算机行业的发展极为快速&#xff0c;搭载于计算机软件运行的数据库管理系统在各行各业得到了广泛的运用&#xff0c;其在数据管理方面具有的准确性和高效性为大中小企业的日常运营提供了巨大的帮助。自从2020年新冠疫情爆发以来&#xff0c;防疫成了社会关注的重中…

RK3568技术笔记七 安装Ubuntu Linux

在新弹出的窗口中&#xff0c;单击“CD/DVD &#xff08;SATA&#xff09;”。如下图所示&#xff1a; 在右侧选择“使用ISO映像文件”。然后单击“浏览”&#xff0c;找到SAIL-RK3568开发板光盘->通用工具->虚拟机Ubuntu->ubuntu-18.04.4-desktop-amd64.iso。最后点击…

探索Vue.js中的文件夹上传解决方案:vue-simple-uploader

在现代Web应用开发中&#xff0c;文件上传是一个常见需求。然而&#xff0c;随着应用复杂性的增加&#xff0c;传统的文件上传方式可能无法满足所有需求&#xff0c;特别是当涉及到文件夹上传和大文件处理时。本文将介绍一个基于Vue.js的解决方案——vue-simple-uploader&#…

MES系统助力制造业数字化转型

一、MES系统的定义和功能 MES&#xff08;Manufacturing Execution System&#xff09;即制造执行系统&#xff0c;是一种可层级化管理生产活动的软件系统。它可以实现对生产过程全面的监控、调度、控制和优化&#xff0c;提高生产的效率、质量和安全性。MES系统具有以下几个主…

最新区块链论文速读--CCF A会议 ICSE 2024 共13篇 附pdf下载 (2/2)

Conference&#xff1a;International Conference on Software Engineering (ICSE) CCF level&#xff1a;CCF A Categories&#xff1a;Software Engineering/System Software/Programming Languages Year&#xff1a;2024 Num&#xff1a;13 第1~7篇区块链文章请点击此处…

电脑技巧:认识全能绘画软件Krita

目录 一、软件简介 二、软件功能 2.1 强大的画笔引擎 2.2专业色彩管理 2.3 多层编辑与管理 2.4 动画制作 三、软件特点 四、安装说明 五、使用技巧 六、快捷键大全 对于喜欢绘画的朋友来说&#xff0c;Krita 是一款不可多得的绘画工具&#xff0c;它具有开源、免费、…

RedHat9 | Mariadb数据库的配置与管理

一、实验环境 1、Mariadb数据库介绍 MariaDB数据库管理系统是一个开源的关系型数据库管理系统&#xff0c;与MySQL高度兼容&#xff0c;并提供了更多的功能和性能优化。 起源和背景 MariaDB是MySQL的一个分支&#xff0c;主要由开源社区维护。由MySQL的创始人Michael Widen…

体验亚马逊AIGC——Amazon Bedrock

前言 随着人工智能技术的不断发展&#xff0c;我们已经进入了一个全新的时代&#xff0c;即AI驱动的时代。在这个时代&#xff0c;人工智能已经逐渐成为我们生活中不可或缺的一部分&#xff0c;它可以帮助我们更好地处理各种复杂的问题&#xff0c;提高我们的工作效率&#xff…

UDP的组播发送与接收C语言测试和nc接收组播测试

组播这个东西&#xff0c;很多年前用过一次。本身的原理不复杂&#xff0c;未知的是使用的环境&#xff0c;受使用环境的影响有多大&#xff0c;还是那句废话&#xff0c;具体问题具体分析。 发送端代码multicast.c #include <stdio.h> #include <stdlib.h> #…

鸿蒙开发:【设置任务快照的图标和名称】

设置任务快照的图标和名称 设置任务快照的图标和名称是为了提高用户界面的可视化性和用户体验&#xff0c;以便更好地管理和跟踪应用程序中的任务和功能。通过为每个任务快照设置不同的图标和名称&#xff0c;可以更轻松地区分和识别每个任务的功能。 默认情况下任务快照的图…

C++基础知识(八:STL标准库 Map和multimap )

Map C 标准模板库&#xff08;STL&#xff09;中的 map 容器是一种非常有用的关联容器&#xff0c;用于存储键值对&#xff08;key-value pairs&#xff09;。在 map 中&#xff0c;每个元素都由一个键和一个值组成&#xff0c;其中键是唯一的&#xff0c;而值则可以重复。 基…

mybatis中resultMap和resultType的区别

总结 基本映射 &#xff1a;&#xff08;resultType&#xff09;使用resultType进行输出映射&#xff0c;只有查询出来的列名和pojo中的属性名一致&#xff0c;该列才可以映射成功。&#xff08;数据库&#xff0c;实体&#xff0c;查询字段,这些全部都得一一对应&#xff09;…

运算符分为哪几类?哪些运算符常用作判断?简述运算符的优先级

运算符包含6大类&#xff1a;算术运算符、赋值运算符、比较运算符、逻辑运算符、位运算符、三元&#xff08;目&#xff09;运算符。 逻辑运算符常用作布尔判断 typeof 运算符: typeof 运算符用于确定变量或表达式的数据类型&#xff0c;并返回一个表示类型的字符串。 typeof …

一文让你清晰了解医疗行业采购堡垒机的必要性

医疗行业&#xff0c;一个与大家息息相关的行业。随着医疗行业的快速发展和信息化建设的深入推进&#xff0c;传统网络安全防护手段已经难以满足现代医疗信息系统的安全需求&#xff0c;特别是在处理敏感的患者信息和保障医院内部数据安全方面。因此采购堡垒机是非常必要的。 堡…

ssm160基于Java技术的会员制度管理的商品营销系统的设计与实现+vue

商品营销系统计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本商品营销系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理…