网络:TCP协议-报头字段

个人主页 : 个人主页
个人专栏 : 《数据结构》 《C语言》《C++》《Linux》《网络》
文章目录
- 前言
- 一、TCP协议格式
- 16位源端口号 和 16位目的端口号
- 4位首部长度
- 16位窗口大小
- 32位序号 和 32位确认序号
- 6种标记位 和 16位紧急指针
- 总结
前言
本文是我对于TCP协议-报头字段的知识总结
一、TCP协议格式

16位源端口号 和 16位目的端口号
16位源端口号:标识发送方应用程序的端口号,是一个16位的字段。通过源端口和目的端口,可以唯一确定一个TCP连接。
16位目的端口号:标识接收方应用程序的端口号,同样是一个16位的字段。与源端口一起,用于确定数据应被哪个应用程序接收。
4位首部长度
TCP协议如何解决 报头和有效载荷分离的问题? 其中 报头 为 TCP标准报头长度(20字节) + 选项。
TCP标准报头长度是固定长度好分离,但选项的长度不确定,该怎么办?
4位首部长度表示 TCP标准报头 + 选项 的大小。
4位首部长度的取值范围为[ 0000, 1111 ]转化为10进制也就是[ 0, 15 ],那这不还没有TCP标准报头长度大吗?我们还规定首部长度的基本单位是4字节,也就说4位首部长度的取值范围是[ 0, 60 ],选项最多40个字节。
现在我们算一下TCP标准报头的4位首部长度,TCP标准报头是20字节,那4位首部长度是5,转化为2进制就是0101 。
注意:TCP的报头长度必须是4的整数倍,因为基本单位是4字节。
16位窗口大小
- 16位窗口大小:表示接收方愿意并能够接收多少数据。用于实现TCP的流量控制机制。
那我们如何理解16位窗口大小?我们先看下图。

我们都知道,TCP具有发送和接受缓冲区,即TCP是全双工通信。发送数据就是把数据拷贝到操作系统内的发送缓冲区,再从发送缓冲区到接收方的接受缓冲区。
那如果发送方一直疯狂的向接收方发送数据,此时发送方不清楚接收方的接受能力(接受缓冲区的剩余空间大小为接受能力),发送方发送数据太快,导致接收方来不及接受数据,接收方的接受缓冲区满了。发送方还是发送数据,那接收方接受到数据,就会直接丢弃。虽然TCP有重传机制,可以重新发送数据,保证可靠性。但这不合理且不高效,数据千辛万苦从网络到接收方,接收方却直接丢弃了。
那要如何使这样的情况合理?如果接收方来不及接受数据了,发送方就慢点发,甚至等会再发。我们把这种如果对方来不及接受,就要求发送方发送变慢,甚至停止发送的策略,叫做流量控制。
对于流量控制的前提是:发送方可以知道接收方的接受能力。那发送方有如何知道接收方的接受能力呢?
这就要先简单的看看确认应答机制了。如 client给server发送一条消息,TCP为了保证可靠性,要求接收方对发送方发过来的消息进行确认,即只要client收到server发送的确认,client就会认为server收到 “hello” 这条消息,保证client 到 server 的可靠性。

要注意其中"hello"这条消息是TCP报文。
现在发送方每发送一条消息,都会收到接收方的应答消息。那么发送方就可以从应答消息中的16位窗口大小来判断,接收方的接受能力,从而避免发送方发送的数据因为接收方缓冲区满了,而直接丢弃的问题。
注意:16位窗口大小,是指自身的接受缓冲区中剩余空间的大小。
32位序号 和 32位确认序号
我们先来看两种TCP发送数据的方式:

先看串行发送,client每发送一条数据后,必须得到server发送的ACK,才能继续发送数据。这样client可以清晰的知道每个ACK对应的是那条数据。这样虽然保证了可靠性,但效率低。
再看并行发送,client可以一次发送多条数据,那么server也要发送对应数量的应答给client(原则上要求server对每一条消息做出应答)。这样client发送时间,进行了重叠,效率得到提升。但这也引来了几个问题。
- client怎么知道那个ACK是哪个发送数据的应答?如果client接受到的ACK与发送数据数量相同,那至少表明client发送的数据,server都收到了。但如果client收到的ACK数量少于发送数据的数量呢?此时client就不清楚那个发送数据没有被server接受到。
- 因为网络环境复杂,server接受到数据的顺序不一定是按照client发送数据的顺序。此时,如果client把报文分两次发送,server就有可能先收到数据,再收到报头;这就不可靠了。
对于上面两个问题,我们可以对发送的数据 和 ACK 进行编号。

此时client就可以根据每个ACK的编号,来确定哪个发送数据被server接受到了。而server也可以根据发送数据的序号,进行排序,从而保证数据的按序到达。
上面的序号就是 32位序号 和 32位确认序号。
- 32位序号:用于对TCP报文段进行编号和排序。每个TCP报文段都有一个唯一的序列号,确保数据的唯一性和可识别性。
- 32位确认序号:用于标识接收端确认收到的数据段。它是成功收到的数据序列号加1,表示接收端已经成功接收了序列号小于该确认序号的所有数据。
注意:32位确认序号还表示,确认序号之前的所有的报文已经被对方全部收到了。为什么要这样规定?允许少量报文的丢失,提高了效率。
如上图,如果server发送的3个ACK,只有序号为301的ACK被client接受到了,那client就会认为发送的3条数据都被server接受到了,效率提升了。
那这里,我们可能会有一个问题?32位序号 和 32位确认序号 可以同一个字段吗?答案是不能。

向上图,client 和 server互相发送信息。在情况1 server对client的回应是发送两条信息,那server可不可以将这两条信息作为一条信息发送?要知道发送的消息都是完整的TCP报文,而ACK只是一个ACK标志位置1的报头,那将报头和 “hello” 数据合并不也是一个完整报文吗?这样不仅对client发送的"hello"进行了应答,而且还对client的信息进行了回复。这些效率进行了提升。像这样报文大都既是数据(需要32位序号,保证按序到达),又是对历史报文的确认(需要32位确认序号),32位序号 和 32位确认序号 同事使用,不能是同一个字段。
6种标记位 和 16位紧急指针
我们知道一个server会被多个client连接,这么多连接,总会有不同的链接请求。

即server一定会同时收到各种各样不同类型的TCP报文,也就表示报文要有类型,如何表示报文的类型?TCP中是6种标记位来表示报文类型。
- URG:紧急指针是否有效
- ACK:确认序号是否有效
- PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走
- RST:对方要求重新建立连接,我们把携带RST标识的称为复位报文段
- SYN:请求建立连接;我们把携带SYN标识的称为同步报文段
- FIN:通知对方,本端要关闭了,我们称携带FIN标识的为结束报文段
这里我们介绍URG,PSH,RST。
URG 和 16位紧急指针

在client 和 server 双方通讯时,TCP报文要按照32位序号排序,按序处理,也就是排队。如果此时 服务器通讯双方有一些紧急数据时,因为TCP报文是有序号的,那该紧急数据也要按序处理吗?这就不好了,我们应该尽快处理紧急数据,即该报文要提前处理,也就是要插队。
此时,我们就需要 URG 和 16位紧急指针。
- URG标记位被置 1 ,表示该报文是紧急报文
- 16位紧急指针表示,在当前报文中,紧急数据在有效载荷中的偏移量
注意:只有URG无效,16位紧急指针也就无效;只有URG被置1,16位紧急指针也要被查看
这就有一个问题。紧急数据的大小是多少?毕竟16位紧急指针只是给了一个地址,并没有给紧急数据有多少个字节。答案是 1个字节。
紧急任务都有哪些?

PSH

当client 给 server 发送 “hello” 时,server要给 client 发送 ACK;但不仅仅只发送 ACK 还会同步 窗口大小。比较发送的是一个完整报文。
如果server因为上层http 处理一个比较耗时的任务,导致进程卡主了。client 给 server 发送 “hello”, server 给 client 发送 ACK ,同时更新窗口大小为 0;

此时表示,server的接受缓冲区满了,client知道不能发送消息了,只能等待。那以后client 如何知道 server 缓冲区的情况,这会不会出现双方互相等待的情况?
并不会,此时client会定期向server发送询问报文(只有报头),根据TCP的确认应答机制,server要给client发送ACK(携带了server的窗口大小)。同时 当上层将接受缓冲区的数据取走,也就是server接受缓冲区的剩余空间 从 0 变为 非0。server 会主动给client发送窗口大小更新报文。

上面两种策略同时使用,那种方式先被client收到,client就会继续发送信息。
其中,client发送的询问报文,就是一个PSH标记位被置1的报头。
注意:PSH不仅仅使用在上述场景中,在所有数据需要尽快交付的场景下,都可以使用。如Linux的指令输入
RST

我们知道TCP通讯的前提,必须进行三次握手。这里有个问题,TCP是保证可靠性的,那是不是三次握手必须成功?不是,三次握手可能失败。那TCP保证可考性是怎么回事,该可靠性不是保证数据100%发送到,而是数据被接收方收到,发送方要知道;数据发送出现问题,发送方也要知道。
现在我们以三次握手出现问题为例,介绍RST出现场景。
我们先要知道对于client 和 server 来说, 什么时候,连接建立好了。
- 对于client,是发出ACK就认为连接建立好了
- 对于server,是要收到client发送的ACK,才认为连接建立好了
注意:这里client 和 server 认为建立好链接有一定的时间差
了解上面这点,我们再往下看。其中SYN 和 SYN + ACK 如果丢包,我们不担心。因为SYN 和 SYN + ACK都有对应的应答,但 ACK 如果丢失,就不好办了。如果client发送的ACK丢包了,但client认为TCP连接已经建立好了,而server因为还没有收到client的ACK,认为还没有建立TCP链接。这就存在了 连接建立认知不一致 。此时client给server发送数据,server会给client发送一个重新建立链接的报文(RST标记位被置1 的报文),此时client会知道发送的ACK丢包了,会重新建立链接。
还有很多其它例子。

下图就是linux-2.6.11.10中tcp的报头字段

总结
TCP保证可靠性,但又不仅仅保证可靠性,还会进行各种提高效率的设定。
以上就是我对于TCP协议的知识总结

相关文章:
网络:TCP协议-报头字段
个人主页 : 个人主页 个人专栏 : 《数据结构》 《C语言》《C》《Linux》《网络》 文章目录 前言一、TCP协议格式16位源端口号 和 16位目的端口号4位首部长度16位窗口大小32位序号 和 32位确认序号6种标记位 和 16位紧急指针 总结 前言 本文是我对于TCP协…...
JAVA基础:HashMap底层数组容量控制,TreeMap底层存取机制,位运算符,原码反码补码
List常用实现类 List集合常用的实现类有3个 , ArrayList , LinkedList , Vector ArrayList 类似于我们之前的ArrayBox 底层使用数组存储元素, 插入删除的效率低,检索的效率高 当底层数组存储容量不足时,会进行扩容,…...
【Redis】Redis 缓存设计:抗住百万并发量的最佳实践
目录 1. Redis 缓存设计原则1.1 高可用性1.2 数据一致性1.3 读写分离 2. 缓存策略2.1 常用缓存策略2.1.1 缓存穿透2.1.2 缓存雪崩2.1.3 缓存击穿 2.2 额外缓存策略2.2.1 更新策略2.2.2 预热策略2.2.3 侧写缓存 3. Redis 架构设计3.1 单机 vs 集群3.2 Redis 集群示例架构 4. 性能…...
【hot100-java】【缺失的第一个正数】
R9-普通数组篇 class Solution {public int firstMissingPositive(int[] nums) {int nnums.length;for (int i0;i<n;i){while(nums[i]>0&&nums[i]<n&&nums[nums[i]-1]!nums[i]){//交换nums[i]和nums[nums[i]-1]int temp nums[nums[i]-1];nums[nums[i]…...
独立站新手教程转化篇:如何做好移动端优化?
随着移动设备在全球范围内的普及,越来越多消费者选择通过手机或平板电脑,来进行线上购物。因此移动端优化,因此移动端优化,也成为独立站卖家必须重视的一个关键环节。那么独立站移动端需要做好哪些优化工作呢? 选择响…...
Mybatis Plus分页查询返回total为0问题
Mybatis Plus分页查询返回total为0问题 一日,乌云密布,本人看着mybatis plus的官方文档,随手写了个分页查询,如下 Page<Question> questionPage questionService.page(new Page<>(current, size),questionService.g…...
VulnHub-Narak靶机笔记
Narak靶机笔记 概述 Narak是一台Vulnhub的靶机,其中有简单的tftp和webdav的利用,以及motd文件的一些知识 靶机地址: https://pan.baidu.com/s/1PbPrGJQHxsvGYrAN1k1New?pwda7kv 提取码: a7kv 当然你也可以去Vulnhub官网下载 一、nmap扫…...
查看和升级pytorch到指定版本
文章目录 查看和升级pytorch到指定版本查看pytorch的版本python 命令查看pytorch的版本使用pip 命令查看当前安装的PyTorch版本升级PyTorch到指定版本 升级到特定的版本 查看和升级pytorch到指定版本 查看pytorch的版本 python 命令查看pytorch的版本 通过Python的包管理工具…...
Maya---机械模型制作
材质效果(4)_哔哩哔哩_bilibili 三角面 四边面 多边面 *游戏允许出现三角面和四边面 游戏中一般是低模(几千个面) 动漫及影视是高模 机械由单独零件组合而成,需独立制作 低面模型到高面模型 卡线是为了将模型保…...
请不要在TS中使用Function类型
在 TypeScript 中,避免使用 Function 作为类型。Function 代表的是“任意类型的函数”,这会带来类型安全问题。对于绝大多数情况,你可能更希望明确地指定函数的参数和返回值类型。 如果你确实想表达一个可以接收任意数量参数并返回任意类型的…...
关于UVM仿真error数量达到指定值就退出仿真的设置
1. 问题描述 在某项目调试过程中,发现通过tc_base.sv中new函数里的set_report_max_quit_count()设置最大error数量不生效,uvm_error数量仍旧是达到10个(默认)就会退出仿真。 2. 设置uvm_error到达一定数量结束仿真的方式 由白皮…...
chatGPT问答知识合集【二】
Redis 架构说明 Redis 是一个开源的内存数据库,它也可以持久化到磁盘。以下是 Redis 的典型架构说明:### Redis 架构组件:1. **客户端**:与 Redis 服务器进行通信的应用程序或客户端库。2. **Redis 服务器**:执行实际…...
不靠学历,不拼年资,怎么才能月入2W?
之前统计局发布了《2023年城镇单位就业人员年平均工资情况》,2023年全国城镇非私营单位和私营单位就业人员年平均工资分别为120698元和68340元。也就是说在去年非私营单位就业人员平均月薪1W,而私营单位就业人员平均月薪只有5.7K左右。 图源:…...
【软考】多核CPU
目录 1. 说明 1. 说明 1.核心又称为内核,是 CPU 最重要的组成部分。2.CPU 中心那块隆起的芯片就是核心,是由单品硅以一定的生产工艺制造出来的,CPU 所有的计算、接收/存储命令、处理数据都由核心执行。3.各种 CPU 核心都具有固定的逻辑结构&…...
制作炫酷个人网页:用 HTML 和 CSS3 展现你的风格
你是否觉得自己的网站应该看起来更炫酷?今天我将教你如何使用 HTML 和 CSS3 制作一个拥有炫酷动画和现代设计风格的个人网页,让它在任何设备上看起来都无敌酷炫! 哈哈哈哈哈哈哈哈,我感觉自己有点中二哈哈哈哈~ 目录 炫酷设计理念构建 HTML …...
WinCC中归档数据片段的时间和尺寸设置
1.归档数据片段介绍工控人加入PLC工业自动化精英社群 1.1 概述 WinCC V6.2 开始的后台数据库采用了MS SQL Server 2005 ,所以归档方式与V5 有所不同,它的运行数据存放在数据片段(segment)当中,工程师可以…...
kubernetes网络(二)之bird实现节点间BGP互联的实验
摘要 上一篇文章中我们学习了calico的原理,kubernetes中的node节点,利用 calico 的 bird 程序相互学习路由,为了加深对 bird 程序的认识,本文我们将使用bird进行实验,实验中实现了BGP FULL MESH模式让宿主相互学习到对…...
动态语言? 静态语言? ------区别何在?java,js,c,c++,python分给是静态or动态语言?
JavaScript 被称为动态语言,而 Java 被称为静态语言 这主要与它们在类型系统、编译执行方式以及运行时行为等方面的不同特性有关。详细差异如下: JavaScript (动态语言) 动态类型: 在JavaScript中,变量的类型是在运行时确定的。这…...
计算机网络17——IM聊天系统——客户端核心处理类框架搭建
目的 拆开客户端和服务端,使用Qt实现客户端,VS实现服务端 Qt创建项目 Qt文件类型 .pro文件:配置文件,决定了哪些文件参与编译,怎样参与编译 .h .cpp .ui:画图文件 Qt编码方式 Qt使用utf-8作为编码方…...
C/C++面试题
关键字 1."#","##"的用法 #是字符串转换符,##是字符串连接符;发生在预处理阶段; 2.volatile的含义 防止编译器优化,告诉编译器每次都去真实地址中读取,而不是从寄存器或者缓存中&a…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...
