【Linux-网络】深入拆解TCP核心机制与UDP的无状态设计

 52bc67966cad45eda96494d9b411954d.png

🎬 个人主页:谁在夜里看海.

📖 个人专栏:《C++系列》《Linux系列》《算法系列》

⛰️ 道阻且长,行则将至


目录

📚引言

📚一、UDP协议

📖 1.概述

📖 2.特点

📚二、TCP协议 

📖 1.概述

📖 2.机制

🔖确认应答(ACK)

🔖超时重传

🔖连接管理

🔖滑动窗口

🔖流量控制

🔖拥塞控制

🔖延迟、捎带应答

📖3.总结


📚引言

在之前的一篇文章中,我们详细介绍了 socket网络编程(基于 TCPUDP),并且在应用层,我们已经能够熟练地调用API来编写简单的服务器和客户端应用。然而,要更好地理解网络编程,我们必须深入了解这两种协议的传输机制和它们的工作原理。今天,我们将通过对 TCPUDP协议的进一步剖析,探索它们在实际传输中的差异、优势和局限性。

🔗文章链接:《【Linux-网络】初识计算机网络 & Socket套接字 & TCP/UDP协议(包含Socket编程实战)》

📚一、UDP协议

📖 1.概述

UDP(User Datagram Protocol,用户数据报协议)是面向报文的协议,即数据是通过报文的形式进行传输,类似于寄信。与 TCP 协议相比,它更加简洁和高效,体现在更少的报文段信息以及没有TCP协议的各种机制。

下面是UDP报文段的标准格式:

UDP数据报由 头部数据部分 两部分组成:

UDP头部(8字节)

① 源端口号(16位):表示发送数据的应用端口。

② 目的端口号(16位):表示接收数据的应用端口。

③ 长度(16位):表示整个UDP报文的长度,包括头部和数据部分的总长度。最大值为64k字节。

④ 校验和(16位):用于检测传输过程中的数据完整性。虽然UDP是可选的,但如果IPv6被使用,校验和是必须的。

UDP数据部分:包括从源应用传来的数据,数据部分的大小由上面提到的 长度字段 决定。

⚠️ 由于UDP数据包的最大长度为64k,当要数据大于这个长度时,就需要进行分包传输。

📖 2.特点

与 UDP 的简洁性相对应地,UDP是 无连接的不可靠的

1️⃣ 面向报文:UDP是面向报文的协议,意味着每次发送的数据包都是一个独立的单位。

2️⃣ 较小的头部开销:UDP头部仅包含 8个字节,相比TCP的20字节头部,UDP的头部开销更小。

3️⃣ 不可靠性:UDP不保证数据的可靠传输,也不保证数据的顺序。如果数据丢失,发送方没有重传机制,接收方无法知道数据丢失。

由于UDP协议的 低延迟简洁性,它特别适合用于对实时性要求高、但对数据可靠性要求较低的场景,例如实时视频通话、在线游戏等。

UDP协议提供的是一种不可靠的数据传输方式,适用于对实时性要求高的场景。然而,当我们需要确保数据包的可靠传输,避免丢包时,TCP协议则成为更合适的选择。 

📚二、TCP协议 

📖 1.概述

TCP(Transmission Control Protocol,传输控制协议)是一种面向连接、可靠的传输层协议。它确保数据能够准确、按顺序地传输到目的地。为了保证数据传输的可靠性和稳定性,TCP报文段就需要包含更多信息。

下面是TCP报文段的标准格式:

其中序列号、确认号、标志位(ACK、SYN等)、窗口大小这些数据段需要结合TCP的特殊传输机制来理解,这里我们先区分一下UDP的报文长度TCP的首部长度

❓前者表示整个报文段的长度,后者仅表示报文头的长度,这是为什么呢?

✅UDP中报文长度这一数据段的作用是使接收方可以正确提取数据,而在TCP中这一职责由序列号+首部长度共同完成,其中序列号表示的是数据区的长度。之所以要标明报头长度是因为,TCP报头是不定长的,除了固定数据段之外,还有可选数据段。

TCP的选项数据段是TCP头部的可选字段,允许在连接建立后对TCP连接进行进一步的配置和优化。选项字段用于扩展TCP协议的功能,提供额外的控制信息,以适应不同的应用需求。

下面我们来一一介绍TCP的各种机制。

📖 2.机制

🔖确认应答(ACK)

我们提到,TCP协议提供的是可靠传输,这当中非常重要的一点是,要避免数据丢包问题,由于网络是不稳定的,数据丢包是很正常的现象。那么发送方怎么知道发送的数据有没有丢失呢?很简单,让接收方接受数据后回应一下,表示数据收到了,这就是TCP的确认应答机制

但是当发送方发送多个数据包后,怎么知道收到的应答是对应哪个数据包的呢,这就需要TCP中的确认号序列号字段了。

序列号每个发送的数据段都被赋予一个唯一的序列号,用于标识数据流中的每一个字节。这个序列号是TCP可靠传输的基础,接收方根据序列号判断数据是否丢失或者是否按正确顺序到达。

确认号接收方使用确认号来告诉发送方,自己已经成功接收到的数据的最后一个字节的序列号。确认号是接收方期望接收的下一个字节的序列号。

每一个ACK都带有对应的确认序列号,表示已接收了哪些数据,下一个数据应该从哪里开始。

🔖超时重传

基于确认应答机制,当发送方过了一段时间后,还没有收到来自接收方的确认应答,就可以判定数据包丢失了,此时就需要重新发送数据包,这就是超时重传机制

这里的丢包分为两种情况:

① 发送的数据包本身丢失了;② 接收方的确认应答丢失了。

无论是哪种情况,都需要重新发送数据包,而对于第二种情况,接收方会收到两个相同的数据包,这个时候根据序列号判断,如果序列号相同,则认为两个数据包相同,会将重复的数据包丢弃,并不影响。

❓这个超时的时间该如何确定呢?

数据包传输到达的时间是会受网络环境影响变化的,如果超时时间设置的太长,会影响重传的效率;如果超时时间设置的过短,则有可能会频繁发送重复的数据包。

✅TCP为了保证在任何环境下都能比较高性能的通信,会动态计算这个超时时间。

以Linux为例,超时时间以500ms为单位,如果重传一次还没有得到应答,则等待2*500ms后再进行重传;之后还得不到应到,则等待4*500ms......直到累计一定的重传次数后,TCP判定网络或目标主机出现异常,强制关闭连接

🔖连接管理

基于TCP协议进行通信的双方,一个基本的前提条件就是,双方都确保能正常发送和接受数据,这样才能保证通信的稳定与可靠性。所以在通信发生之前,需要对双方的发送、接受能力进行验证;同样地,在通信结束时,也需要确保双方都已关闭连接信道,避免单方面发送数据却不能被接收也等不到应答的情况。这就是三次握手与四次挥手机制。 

在理解三次握手与四次挥手之前,我们需要了解一个预备知识,那就是TCP报文段的标志位

TCP报文段中的标志位(也叫控制位)用于控制TCP连接的建立、维护和终止。每个TCP报文段中都有一个6位的标志字段,分别是:

① URG(紧急标志):用于指示数据段中有紧急数据需要处理

② ACK(确认标志):表示确认号字段有效,即接收方通过确认号来告知发送方它期望接收的下一个字节的序列号

③ PSH(推送标志):表示接收方应该立即将数据推送给应用层

④ RST(重置标志):强制断开TCP连接,用于一方出现错误或不可恢复的异常的情况

⑤ SYN(同步标志):用于连接的建立,表示请求连接或响应连接请求

⑥ FIN(终止标志):用于连接的断开,表示发送方没有数据要发送,并请求关闭连接

在TCP三次握手过程中,SYN标志位会在第一次和第二次握手时被使用:

1️⃣ 客户端发起连接时,会发送一个带SYN标志的报文,表示请求建立连接。

2️⃣ 服务器响应客户端请求时,也会发送一个带SYN标志的报文来表示同意连接。

在TCP四次挥手过程中,FIN标志位被用来发起和响应连接的终止

1️⃣ 主动关闭连接的一方会发送带有FIN标志的报文,表示它已经完成数据传输并希望关闭连接。

2️⃣ 被动关闭的一方也会发送带有FIN标志的报文作为确认,表示它同意终止连接。 

下面是三次握手的全过程:

① 第一次握手:通信发起方向接收方发送SYN报文,请求连接(打开写端,表示我要写数据了)

② 第二次握手:接收方收到SYN报文,回复ACK报文,表示同意连接请求(打开读端,表示我能收到数据);并同时也发送SYN报文(打开写端,我也要写数据了)

③ 第三次握手;发起方收到SYN报文,同意回复ACK报文(打开读端,表示我也能收到数据)

四次挥手的全过程:

① 第一次挥手:断开连接发起方向接收方发送FIN报文,表示希望关闭连接(关闭写端,表示不再写数据了)

② 第二次挥手:接收方收到FIN请求,回复ACK表示同意(关闭读端,我不再等待接收数据了)

③ 第三次挥手:接收方发送FIN请求(关闭写端,我也不写数据了) 

④ 第四次挥手:发起方收到FIN请求,回复ACK表示同意(关闭读端,我也不等待接收数据了)

从上面的步骤来看,其实第二次握手是包含两步的:接收方打开读端与写端,这与第二次挥手、第三次挥手是对应上的,问题来了:

❓① 为什么要把接收方打开读端与写端的操作合并为一步;② 为什么接收方断开读端和写端的操作不能合并成一步。

✅先回答第一个问题,我们要知道,每一个标志位的独立发送都需要独立的报文段,接收方要分别发送ACK与SYN的话就需要占用两个报文段,既然如此,为什么不把这两步合成一步,节省资源呢,于是就有了第二次握手。

✅对于第二个问题,断开连接发起方发送FIN报文的意思是,不会再发送数据了,也就是关闭了写端,但这并不意味着读端也关闭了;同样地,接收方在收到FIN报文后回复ACK的意思是,关闭读端,但也不意味着写端就要一并关闭,相反地,它依旧可以发送数据,对方也依旧可以收到数据,因此二、三挥手要分开来执行。

在TCP协议中,连接的建立与断开遵循严格的状态变化流程。理解连接发起方、接收方以及断开发起方、接收方的状态变化对理解TCP的三次握手(连接建立)和四次挥手(连接终止)至关重要。

连接建立(TCP三次握手)

① 连接发起方(客户端)

        初始状态:CLOSED(连接关闭);

        发送SYN请求:客户端进入 SYN_SENT 状态,发送一个SYN报文;

        接收ACK响应 确认连接建立,进入 ESTABLISHED 状态,开始数据的双向传输。

② 连接接收方(服务器)

        初始状态:LISTEN(监听状态)

        接收SYN请求: 进入 SYN_RCVD 状态,并发送一个带有SYN和ACK标志的响应报文(SYN-ACK),表示同意建立连接。

        等待确认: 收到客户端的确认ACK报文后,连接成功建立,进入 ESTABLISHED 状态,开始数据的双向传输。

三次握手过程状态变化图

  • 客户端(发起方): CLOSEDSYN_SENTESTABLISHED
  • 服务器(接收方): LISTENSYN_RCVDESTABLISHED

连接断开(TCP四次挥手) 

① 连接断开发起方(客户端/服务器)

1. 初始状态:ESTABLISHED(已建立连接);

2. 发送FIN请求:此时,该端点的写端被关闭,进入 FIN_WAIT_1 状态;

3. 等待ACK响应: 主动关闭方在 FIN_WAIT_1 状态等待接收方的ACK报文确认其断开请

4. 等待接收方的FIN: 此时,主动关闭方进入 TIME_WAIT 状态,等待足够的时间确保接收方收到了最后的ACK报文。

② 连接断开接收方(服务器/客户端)

1. 初始状态:ESTABLISHED(已建立连接);

2. 接收FIN请求: 被动关闭的一方在 ESTABLISHED 状态收到主动关闭方的FIN报文后,进入 CLOSE_WAIT 状态,表示确认收到对方的断开请求,并准备关闭自己的写端。

3. 发送ACK响应: 被动关闭方发送ACK报文,确认收到对方的FIN报文。此时,它的写端被关闭,但接收端仍然保持开放,允许接收剩余的数据。

4. 发送FIN: 当被动关闭方完成数据接收后,主动发送带有FIN标志的报文,表示自己也没有数据要发送了,进入 LAST_ACK 状态。

5. 等待确认: 被动关闭方等待对方的ACK确认,确认连接完全断开后,进入 CLOSED 状态。

四次挥手过程状态变化图

  • 主动关闭方:
    • ESTABLISHEDFIN_WAIT_1FIN_WAIT_2TIME_WAITCLOSED
  • 被动关闭方:
    • ESTABLISHEDCLOSE_WAITLAST_ACKCLOSED

🔖滑动窗口

基于确认应答机制,如果每发送一次报文,都需要等待应答,收到ACK后再发送下一个报文,这样做会大大影响性能。于是我们可以一次性发送多个报文,并且同时等待多个应答,因为发送的报文是基于序列号顺序发送的,所以可以看作一个滑动窗口,窗口内部是已发送但还未收到应答的报文,当收到应答后,右移窗口的左端;发送新报文后,右移动窗口右端。这就是滑动窗口机制。

❓如果在发送过程中出现丢包,该如何解决?这里分两种情况:

① 数据包已抵达,但ACK丢了。这种情况下,基于超时重传机制,发送方会重新发送数据包,直到接收到相应的ACK为止

② 数据包丢失了。例如,发送方一共发送了序列号为1~5000的数据包,但是当中1001~2000的数据包丢失了,其余的没有丢失。在这种情况下,接收方返回的确认序列号会一直为1001,表示1001开头的报文没有收到,此时发送方得知后会重新发送1001~2000的数据包,此时接收方返回的确认序列号为5001(因为2001~5000的数据包已经收到了)。

这种机制被称为“高并发重传机制”。

🔖流量控制

接收方收到数据包后时并不会立即处理,而是暂存在接收缓冲区中,而缓冲区的空间时有限的,这就意味着如果发送方一次性发送过多数据包,就会出现由于缓冲区空间不足而丢包的情况。 为了避免这种情况的发送,发送方就需要控制发送速度,就需要借助流量控制机制

控制速度的依据是接收方的缓冲区剩余空间大小,而发送方该怎么得知这一信息呢,就需要借助TCP报文段中的“窗口大小”字段。

接收方依据缓冲区剩余空间,设置窗口大小并通过ACK应答报文告知发送方,如果窗口大小变小,发送方就会减缓发送速度;如果窗口大小为0,发送方就停止发送数据,但是会时不时发送窗口探测,用于探测请求接收方窗口更新。

❓即使发送方不进行窗口探测,接受方在缓冲区有空间剩余之后还是会发送窗口更新报文,但是为什么发送方还是需要时不时进行探测呢?

✅因为接收方的窗口更新报文有可能丢失,如果发送方不探测,接收方就不会重传

🔖拥塞控制

基于流量控制机制,发送方在数据发送的过程中可以很好地控制速度,但是还存在一个问题,那就是在刚建立通信连接,第一次发送数据时,并不知道接收方的缓冲区情况,此时并不能确定该发送多少数据。于是TCP引入慢启动机制,即一开始只发送少量数据,目的是探测对方的“吞吐量”大小,清楚情况后,再决定用什么速度传输数据。

那么这个传输速度具体该如何确定呢?这里要引入“拥塞窗口”的概念:

数据发送开始时,拥塞窗口为1;此后每收到一个ACK,拥塞窗口加1,并取拥塞窗口与ACK中窗口大小的较小值作为本次发送数据的大小。

如此一来,数据发送速率是呈指数级增长的,但是这到了后面,速度会变得很不可控,并且很大概率会出现丢包(发送速度过快),因此要对速度进行限制,就需要借助“慢启动阈值”这一概念。

当拥塞窗口超过阈值时,就不再按指数级增长,而是按线性增长。这个阈值初始为窗口最大值,之后每发送一次超时重传,阈值变为原来的一半,并且拥塞窗口置为1(将阈值慢慢逼近一个合理值,既保证了传输效率,又减少了出现丢包的可能性)

🔖延迟、捎带应答

接收方在ACK应答的同时,也在处理缓冲区的数据,也就是说,如果ACK立即应答,其时效性会比较低下(剩余空间远大于窗口值,因为一部分数据已被处理),于是TCP引入了延迟应答机制接收方在接收数据之后,会等待一段时间再发送ACK应答,这样在一定程度上可以确保窗口大小的时效性

基于延迟应答,接收方的数据包发送和ACK应答可以共用一个数据段,这样可以大大节约资源,第二次握手就是很好的例子。 

📖3.总结

TCP协议通过以上多种机制确保了数据传输的可靠性,并且通过一系列优化手段提升传输性能。因此,以上机制可以大致分为两类:可靠性机制性能优化机制

                             可靠性机制                          性能优化机制
                                校验和                             滑动窗口
                        序列号(按序到达)                             快速重传
                               确认应答                             延迟应答
                               超时重发                             捎带应答
                               连接管理
                               流量控制
                               拥塞控制

以上就是【深入拆解TCP核心机制与UDP的无状态设计】的全部内容,欢迎指正~ 

码文不易,还请多多关注支持,这是我持续创作的最大动力!

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

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

相关文章

一文学会Spring

一、Spring简介 Spring的优点 Spring是一个开源免费的框架、容器Spring是一个轻量级的框架,非侵入式的控制反转IOC、面向切面AOP支持事务 Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器 二、IOC 2.1 IOC本质 控制反转IOC,是一种设计思想…

AWR microwave office 仿真学习(三)各类传输线模型学习

目录 引言Phase Spec: Coupled Lines (Closed Form): CLINPhysical Spec: Coupled Lines, Grounded Shield, Improved Accuracy (Closed Form): CLINPPhysical Specification, Floating Shield (Closed Form): COAXElectrical Specification, Grounded Shield (Closed Form): C…

TrustRAG:通过配置化模块化的检索增强生成(RAG)框架提高生成结果的可靠性和可追溯性

TrustRAG旨在风险感知的信息检索场景中提高生成内容的一致性和可信度。用户可以利用私有语料库构建自己的RAG应用程序,研究库中的RAG组件,并使用定制模块进行实验。论文展示了TrustRAG系统在摘要问答任务中的应用,并通过案例研究验证了其有效性。总体而言,TrustRAG通过语义…

pgsql行列转换

目录 一、造测试数据 二、行转列 1.函数定义 2.语法 3.示例 三、列转行 1.函数定义 2.语法 3.示例 一、造测试数据 create table test ( id int, json1 varchar, json2 varchar );insert into test values(1,111,{111}); insert into test values(2,111,222,{111,22…

计算机视觉算法实战——人脑解码(主页有源码)

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​ ​​​ 1. 领域简介 人脑解码(Brain Decoding)是神经科学与计算机视觉交叉领域的一个重要研究方向,旨在…

[Computer Vision]实验六:视差估计

目录 一、实验内容 二、实验过程 2.1.1 test.py文件 2.1.2 test.py文件结果与分析 2.2.1 文件代码 2.2.2 结果与分析 一、实验内容 给定左右相机图片,估算图片的视差/深度;体现极线校正(例如打印前后极线对)、同名点匹配…

【Mac】git使用再学习

目录 前言 如何使用github建立自己的代码库 第一步:建立本地git与远程github的联系 生成密钥 将密钥加入github 第二步:创建github仓库并clone到本地 第三步:上传文件 常见的git命令 git commit git branch git merge/git rebase …

从0搭建Tomcat第二天:深入理解Servlet容器与反射机制

在上一篇博客中,我们从0开始搭建了一个简易的Tomcat服务器,并实现了基本的HTTP请求处理。今天,我们将继续深入探讨Tomcat的核心组件之一——Servlet容器,并介绍如何使用反射机制动态加载和管理Servlet。 1. Servlet容器的作用 S…

文件上传漏洞:upload-labs靶场11-20

目录 pass-11 pass-12 pass-13 pass-14 pass-15 pass-16 pass-17 pass-18 pass-19 pass-20 pass-11 分析源代码 ,发现上传文件的存放路径可控 if(isset($_POST[submit])){$ext_arr array(jpg,png,gif);$file_ext substr($_FILES[upload_file][name],st…

【音视频】视频基本概念

一、视频的基本概念 1.1 视频码率(kb/s) 视频码率是指视频文件在单位时间内使用的数据流量,也叫码流率。码率越大,说明单位时间内取样率越大,数据流进度也就越高 1.2 视频帧率(fps) 视频帧率…

Sqlserver还原备份文件时提示缺少日志文件

Sqlserver还原备份文件时提示缺少日志文件 解决方案:

《2025年软件测试工程师面试》消息队列面试题

消息队列 消息队列(Message Queue,简称 MQ)是一种应用程序之间的通信方法。 基本概念 消息队列是一种先进先出(FIFO)的数据结构,它允许一个或多个消费者从队列中读取消息,也允许一个或多个生产者…

前端基础之vuex

是一个专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式管理(读或写),也是一种组件间通信的方式,适用于任意组件间的通信 什么时候使用vuex? 1.多组件依赖同一状态 2.来自不同组件的行…

Node.js二:第一个Node.js应用

精心整理了最新的面试资料和简历模板,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 创建的时候我们需要用到VS code编写代码 我们先了解下 Node.js 应用是由哪几部分组成的: 1.引入 required 模块:我们可以使用 requi…

Python学习(十四)pandas库入门手册

目录 一、安装与导入二、核心数据结构2.1 Series 类型(一维数组)2.2 DataFrame 类型(二维数组) 三、数据读取与写入3.1 读取 CSV 和 Excel 文件3.2 写入数据 四、数据清洗与处理4.1 处理缺失值4.2 数据筛选4.3 数据排序 五、数据分…

2025东方财富笔试考什么?cata能力测评攻略|答题技巧真题分享

嘿,各位怀揣金融梦想、准备在 2025 年求职浪潮中大展身手的小伙伴们! 我是职小豚,在求职指导领域摸爬滚打了 10 年,每年都见证着无数求职者为心仪的岗位全力以赴。 一、东方财富:金融科技界的“数据狂魔” 东方财富&…

Ollama+AnythingLLM安装

一、文件准备 ‌ 1. 安装包获取‌ 从联网设备下载: AnythingLLMDesktopInstaller.exe(官网离线安装包)‌ deepseek-r1-1.5b.gguf(1.5B 参数模型文件)‌ 2. ‌传输介质‌ 使用 U 盘或移动硬盘拷贝以下文件至离线设…

java后端开发day27--常用API(二)正则表达式爬虫

(以下内容全部来自上述课程) 1.正则表达式(regex) 可以校验字符串是否满足一定的规则,并用来校验数据格式的合法性。 1.作用 校验字符串是否满足规则在一段文本中查找满足要求的内容 2.内容定义 ps:一…

Storm实时流式计算系统(全解)——下

storm编程案例-网站访问来源实时统计-需求 storm编程-网站访问来源实时统计-代码实现 根据以上条件可以只写一个类,我们只需要写2个方法和一个main(),一个读取/发射(spout)。 一个拿到数据统计后发到redis…

【0010】Python流程控制结构-分支结构详解

如果你觉得我的文章写的不错,请关注我哟,请点赞、评论,收藏此文章,谢谢! 本文内容体系结构如下: 分支结构是编程中的基本控制结构之一,它允许程序根据条件判断执行不同的代码路径。通过本文&…