首页/新闻资讯/正文详情

Linux网络(十四):TCP协议详解:从“报文”理解到TCP报头与字节流本质,彻底搞懂数据交付与分离

发布时间:2026/9/24 17:29:44 来源:云帆数科 栏目:资讯中心
Linux网络(十四):TCP协议详解:从“报文”理解到TCP报头与字节流本质,彻底搞懂数据交付与分离
◆ 博主名称 小此方-CSDN博客大家好欢迎来到小此方的博客。⭐️网络系列个人专栏 【主题曲】计算机网络⭐️此方的GitHub github_此方⭐️我们思考 (Rethink) · 我们重建 (Rebuild) · 我们记录 (Record)文章目录概要序論一、重构我们对报文的理解1.1怎么管理呢——先描述再组织1.2所谓的封装和解包本质就是移动 data 指针在缓冲区中的指向1.3回看封包过程与并发思考二、TCP 报头与字节流本质2.1标准问题如何交付、如何分离2.2新问题为什么 TCP 报头中没有报文大小的字段概要序論Hello大家好我是此方。上一篇我们讲解了UDP的深入理解从本文开始我将花费非常非常多的篇幅讲解TCP的底层原理内容。这里也是校招面试的高频考点密集区。理解原理比强记八股更加重要。好我们开始吧。一、重构我们对报文的理解在网络通信中客户端与服务器往往是n : 1 n:1n:1的关系。多个客户端同时向服务器发送报文这意味着在操作系统OS内部必然会同时存在着海量的报文——既然存在海量报文OS 就必须管理这些报文1.1怎么管理呢——先描述再组织操作系统管理报文的核心思路依然是“先描述再组织”在 Linux 内核中通过struct sk_buff结构体来描述报文。结构体内包含了struct sk_buff *next和struct sk_buff *prev指针用以构建报文之间的双向链表连接。由此可以得出核心结论报文 结构体 内存缓冲区。把这个结构抽象出来看sk_buff结构体内部包含head、data、tail、end指针。指针指向的是一块连续的内存数据区分为头空间、二层帧头、IP协议头、TCP/UDP协议头、应用层数据、尾空间。1.2所谓的封装和解包本质就是移动 data 指针在缓冲区中的指向报文在传输时是如何移动指针的答案是± \pm±对应的协议长度。在数据封装时tail指针保持不动data指针向上低地址方向移动对应的协议长度即data - sizeof(struct udphdr)移动后直接使用强转后的data指针写入对应的报头数据例如(struct udphdr*)data-...反之在解包时只需要将data指针向下高地址方向移动剥离协议头即可。你也可以理解为报文在哪一层就在哪一个队列中网络四层结构中对应存在着四个skbuf队列。1.3回看封包过程与并发思考我们回过头来看传统的封包理解应用程序创建缓冲区填入报文⟶ \longrightarrow⟶传输层创建空结构⟶ \longrightarrow⟶应用层将报文拷贝到传输层整个过程和思路板书这里引出一个核心问题如果应用层正在进行报文的解析、处理会不会影响 OS 从网络中读取报文为什么答案是不会因为不论是应用层的数据操作还是系统层的数据接收本质上都是响应硬件中断或时钟中断在逻辑上不分先后。在现代计算机体系中更有 DMA直接内存访问等先进技术能够保证硬件层面 independent、高效地接收网络数据。二、TCP 报头与字节流本质TCP 全称为“传输控制协议”Transmission Control Protocol。人如其名它的核心职责就是要对数据的传输进行一个详细且精确的控制。从系统的角度来看 TCP 传输以我们以前学习的文件系统为例文件struct file有一个缓冲区我们调用写入操作时是向缓冲区写入而不是直接向外设写入。TCP 传输也是同样的道理write系统调用只需要往缓冲区写入不需要阻塞等待报文被发送到目标而是可以直接继续执行应用层的工作。我们可以把报文发送理解为“一次比较复杂的刷新”。这样可以显著提升效率。为了深入理解 TCP 是如何控制数据传输的我们必须先理清协议设计中的基本问题。2.1标准问题如何交付、如何分离这是TCP报文的格式抽象图:网络协议在设计时必须回答两个最核心的机制问题报头和有效载荷如何分离如何交付关于如何交付直接提取 TCP 报头中的16位目的端口号操作系统就知道该把数据交付给哪一个应用层进程了。那么报头和有效载荷又是如何分离的呢关键就在于报头中的4位首部长度。4 位二进制能表示的数字范围是 0000~1111即 0~15。如果一个数字代表 1 个字节那么首部最大只能表示 15 个字节这显然是不够用的。因此我们约定基本单位一定是 4 个字节即 1 个数值代表 4 个字节。同时报文必须是 4 字节的整数倍。由此可以推算出 TCP 报头的长度逻辑报头大小的理论范围是 0~60 字节15 × 4 15 \times 415×4。但 TCP 标准报头至少有固定的20 个字节再加上可变长度的选项部分。所以报头实际大小范围被缩小为20~60 字节。映射到 4 位首部长度的二进制取值就是0101~1111即 5~15。此外选项的长度也必须是 4 字节的倍数。有了这些知识报头与有效载荷的分离流程就非常清晰了首先固定读取报头的前 20 个字节。提取出其中的 4 位首部长度x xx。计算得到报头总长度为x × 4 x \times 4x×4。通过公式4 × x − 20 4 \times x - 204×x−20计算出选项的长度。剥离掉计算出的总报头长度剩下的全部就是有效载荷应用层数据了。2.2新问题为什么 TCP 报头中没有报文大小的字段有人可能会问会不会出现上面的有效载荷和下一个报头混在一起的情况答案是不存在因为在系统的底层我们的每一个报文都是一个独立的sk_buf至于为什么 TCP 报头不需要设计“报文大小”或“数据长度”的字段这源于 TCP 的核心设计理念TCP 是面向字节流的传输层协议它只负责将字节序列可靠、有序地送达接收缓冲区。TCP 不关心也不理解应用层业务报文的边界即无“报文界限”因此首部无需设置“应用层报文大小”字段。应用层数据的拆分与拼装粘包/半包处理完全需要由应用层协议自行定义和解析。不关心职责分工TCP 是传输层协议它的唯一使命是保障字节能不丢包、不乱序地送达对方。至于这些字节代表的是一张图片、一段 JSON 还是一个 HTTP 请求TCP 不需要也不应该去干涉。不理解数据结构TCP 看到的只有 0101 的二进制字节流。它不知道哪个字节是消息的开头Header哪个字节是消息的结尾Footer。好的本期内容就到这里如果对你有帮助还不要忘记点赞三联支持。我是此方我们下期再见。bye!

相关推荐

Spring 引入外部属性配置文件详解
Spring 引入外部属性配置文件详解

Spring 引入外部属性配置文件详解 一、为什么需要外部属性文件? 在实际项目中,数据库连接、第三方 API 密钥、服务器地址等配置通常不应该硬编码在 XML 或 Java 代码中。原因有三: 环境差异:开发、测试、生产环境的数据库地址不同… · 2026/9/24 17:29:38

基于微信小程序的校内二手交易系统-附源码文档
基于微信小程序的校内二手交易系统-附源码文档

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台… · 2026/9/24 17:29:38

告别System.out.println!IDEA 2026.2日志点无痛调试保姆级教程
告别System.out.println!IDEA 2026.2日志点无痛调试保姆级教程

写代码的谁没干过这事?程序出Bug了,疯狂往代码里塞System.out.println,打完日志、定位完问题,又得一个个删掉。 最崩溃的是:改一行代码,重启服务、重部署、重测一遍,来回折腾半小时,… · 2026/9/24 17:29:32

软考培训班怎么选不踩坑,五个维度给你讲透
软考培训班怎么选不踩坑,五个维度给你讲透

软考培训班从几百到上万都有,到底差在哪?好多人报班之前只看价格,报完才发现这也没有那也不含,再想退就难了。今天把选软考培训班要注意的五个维度给你讲清楚,照着对比就不会踩坑。选班看什么好多人选培训班就看一条&a… · 2026/9/24 19:14:00

SpringBoot整合Netty实现高性能WebSocket:粘包心跳与避坑指南
SpringBoot整合Netty实现高性能WebSocket:粘包心跳与避坑指南

1. 为什么我放弃了Spring原生WebSocket,转头上了Netty先交代一下背景。我这边有个项目,前期用的是SpringBoot自带的WebSocket(基于WebSocketHandler和STOMP那套),单机几百个连接的时候一切正常。等业务量上来&#xff… · 2026/9/24 19:14:00

【Python 异常机制详解:掌握 try except 捕获异常】
【Python 异常机制详解:掌握 try except 捕获异常】

Python 中,用try except语句块捕获并处理异常,其基本语法结构如下所示:try:可能产生异常的代码块 except [ (Error1, Error2, ... ) [as e] ]:处理异常的代码块1 except [ (Error3, Error4, ... ) [as e] ]:处理异常的代码块2 except [Excep… · 2026/9/24 19:14:00

Java实现中国象棋:从棋盘建模到Alpha-Beta剪枝的完整解析
Java实现中国象棋:从棋盘建模到Alpha-Beta剪枝的完整解析

简介:一套基于 Java 实现的《中国象棋》完整游戏源码,面向有一定 Java 基础、想深入游戏逻辑与算法设计的开发者。项目实现了棋盘与棋子的图形界面、不同棋子的走法限制、走子音效,并采用极大极小值搜索算法构建 AI;支持人机、人人… · 2026/9/24 19:13:53

净化板材选型与施工全解析:从洁净等级到气密性验收
净化板材选型与施工全解析:从洁净等级到气密性验收

1. 净化板材的基本认知与分类做净化工程这些年,我见过太多人把净化板当成普通彩钢板用,结果后面返工、整改、验收不过关,一堆麻烦事。实际上净化板材和普通建材板完全是两个思路的产物,它本质上是一种“服务于空气洁净度控制”的结… · 2026/9/24 19:13:53

服务器硬件测试选型指南:从资源画像到套餐化实践
服务器硬件测试选型指南:从资源画像到套餐化实践

1. 从一台"看起来没问题"的服务器说起机房巡检的时候,最怕遇到那种"什么告警都没有,但业务就是慢"的机器。CPU使用率不高,内存也够,磁盘IO看着也正常,可一到业务高峰期,响应时间就往上… · 2026/9/24 19:13:53

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13

1D-CNN时间序列建模实战:从Conv1d原理到工业落地
1D-CNN时间序列建模实战:从Conv1d原理到工业落地

简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26

柔软的L:汉语语流中被忽视的舌肌张力控制
柔软的L:汉语语流中被忽视的舌肌张力控制

1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码