TCP 三次握手与四次挥手:构建与终止可靠通信的核心机制

news/2025/2/21 7:45:24/

引言

TCP(传输控制协议)是网络通信的基石,其核心目标是:

        在不可靠的IP层之上提供可靠的数据传输

        为实现这一目标,TCP通过 三次握手(Three-way Handshake)建立连接,通过四次挥手(Four-way Handshake) 终止连接。本期文章我将以通俗易懂的方式解析这两个关键过程的技术细节,并探讨其设计背后的逻辑。


一、三次握手:建立可靠通信信道

1 TCP 报文标志

        TCP 协议就像两个人打电话,需要一些“暗号”来协调对话的开始、结束和确认。这些“暗号”就是报文中的标志位,每个标志代表一个特定动作。

1. SYN(Synchronize,同步标志)

  • 作用:打招呼,告诉对方“我要和你建立连接”。
  • 例子:你打电话给朋友,开口说:“喂,能听到吗?”——这就是 SYN
  • 技术细节:携带初始序列号(类似对话的起始编号),用于三次握手的第一步。

2. ACK(Acknowledgment,确认标志)

  • 作用:确认收到对方的消息,回应“我收到了”。
  • 例子:朋友回答:“能听到!”——这就是 ACK
  • 技术细节ACK 必须配合一个确认号(Acknowledgment Number),表示“我期待你下次从这个编号开始发数据”。

2 握手过程分解

三次握手的目标是同步双方的初始序列号(Sequence Number),确认双方的收发能力正常。具体流程如下:

三次握手过程
步骤方向报文标志状态变化核心作用
第一次握手客户端 → 服务端SYN=1,ACK=0,SEQ(顺序号)=x客户端进入SYN_SENT客户端声明自身具备发送能力
第二次握手服务端 → 客户端SYN=1, ACK=1, SEQ=y, ACK=x+1服务端进入SYN_RCVD服务端确认客户端发送能力,声明自身具备收发能力
第三次握手客户端 → 服务端ACK=1, ACK=y+1双方进入ESTABLISHED客户端确认服务端具备收发能力

三次握手的生活例子:打电话确认身份
假设你(客户端)想给朋友(服务端)打电话确认一件事:

第一次握手(SYN):你拨通电话,说:“喂,是老陈吗?”(你发起连接请求)。
第二次握手(SYN-ACK):朋友接听后回答:“是的,我是老陈。你是小梁吗?”(朋友确认你的请求,并反问你的身份)。
第三次握手(ACK):你回答:“对,我是小梁!”(你确认朋友的身份,双方明确彼此身份)。
此时,双方确认了对方的身份和通信能力,可以开始正式对话。

关键点:三次确认确保双方身份和通信能力可靠,避免“假电话”或“听不清”的问题。


如果还听不懂,没关系,下面我再总结一遍三次握手过程:

握手阶段客户端确认内容服务端确认内容
第一次握手仅自身发送能力客户端发送能力 + 自身接收能力
第二次握手双方收发能力客户端发送能力 + 自身接收能力
第三次握手双方信道就绪自身发送能力 + 客户端接收能力
  • 第一次握手
    • 客户端确认内容:客户端就只看看自己有没有本事把消息发出去,比如检查一下自己的网络设置、相关软件是不是能正常发数据等,只关心自己的发送能力。
    • 服务端确认内容:服务端收到客户端发过来的消息后,一方面知道了客户端有发消息的能力,另一方面也看看自己能不能正常接收消息,比如检查自己的接收端口是不是开着,接收数据的程序是不是在正常运行等。
  • 第二次握手
    • 客户端确认内容:客户端收到服务端的回应后,就知道自己能给服务端发消息,服务端也能收到,同时服务端也能给自己回消息,这就确认了双方的收发能力都是正常的。
    • 服务端确认内容:和第一次握手时差不多,还是确认客户端能发消息给自己,同时自己的接收能力也是好的,没有变化。
  • 第三次握手
    • 客户端确认内容:客户端发送消息给服务端,就是告诉服务端 “我这边一切准备就绪啦,咱们可以开始正式通信啦”,表明双方的通信信道都准备好了,可以正常传输数据了。
    • 服务端确认内容:服务端收到客户端的这个消息后,就知道客户端已经准备好接收数据了,同时也再次确认自己给客户端发消息的能力是没问题的,这样双方就可以正式开始进行数据交互了。


关键设计解析

  • 为什么需要三次而非两次?
    若仅两次握手,服务端无法确认客户端是否收到自己的SYN-ACK。若客户端未收到此包,服务端会持续等待,导致资源浪费(如半连接队列堆积)。三次握手确保双方均确认对方的收发能力。(全双工通信

  • 半连接队列(SYN Queue)与全连接队列(Accept Queue)

    • 半连接队列:存储未完成三次握手的连接(SYN_RCVD状态),用于防御SYN Flood攻击(通过限制队列大小)。
    • 全连接队列:存储已完成握手的连接(ESTABLISHED状态),等待应用调用accept()处理。
  • 第三次握手可携带数据
    客户端在第三次握手时即可发送数据(如HTTP请求),而服务端需完成第三次握手后才能发送数据。这一设计优化了通信效率。


二、四次挥手:优雅终止全双工连接

1 挥手过程分解

由于TCP是全双工协议,双方需独立关闭数据通道。流程如下:

四次挥手过程
步骤方向报文标志状态变化核心作用
第一次挥手主动关闭方 → 被动关闭方FIN=1, SEQ=u主动方进入FIN_WAIT_1主动方停止发送数据
第二次挥手被动关闭方 → 主动关闭方ACK=1, ACK=u+1被动方进入CLOSE_WAIT,主动方进入FIN_WAIT_2确认收到关闭请求
第三次挥手被动关闭方 → 主动关闭方FIN=1, SEQ=v被动方进入LAST_ACK被动方停止发送数据
第四次挥手主动关闭方 → 被动关闭方ACK=1, ACK=v+1主动方进入TIME_WAIT,被动方关闭确认最终关闭

2 四次挥手的生活例子:礼貌结束对话

假设你和同事在会议室讨论工作,结束后需要离开:

  1. 第一次挥手(FIN):你说:“我的部分讲完了,我先走了。”(你主动提出结束对话)。
  2. 第二次挥手(ACK):同事回答:“好的,我知道了。”(同事确认你的结束请求,但可能还有话要说)。
  3. 第三次挥手(FIN):同事补充:“对了,下周的会议时间别忘了!”(同事完成自己的发言后,也提出结束对话)。
  4. 第四次挥手(ACK):你回答:“没问题,我会记住的!”(你确认同事的结束请求)。
    至此,双方都确认对话结束,各自离开会议室。

关键点

  • 双方需独立确认结束,因为可能各自有未说完的内容(类似TCP的全双工特性)。
  • 最后你等待片刻(类似TIME_WAIT状态),确保同事没有突然回头补充内容(防止数据丢失)。

关键设计解析

  • 为什么需要四次挥手?
    被动关闭方可能在收到FIN后仍有数据待发送(如服务器需发送最后响应),因此需将ACKFIN分开发送。

  • TIME_WAIT状态的意义

    • 确保最后一个ACK到达:若该ACK丢失,被动方会重传FIN,主动方可再次响应。
    • 防止旧连接数据干扰:等待2MSL(报文最大生存时间,通常60秒)确保网络中残留的旧报文失效。
  • CLOSE_WAIT状态积压问题
    若程序未正确调用close(),会导致大量连接滞留CLOSE_WAIT状态,引发资源泄漏。需通过代码审查或监控工具排查。

三、总结

通过生活化的例子,可以直观理解:

  • 三次握手是“建立信任”的过程,确保双方能正常通信。
  • 四次挥手是“礼貌告别”的过程,确保双方数据完整传输后终止连接。
    这种机制保障了TCP协议在不可靠的网络环境中实现可靠传输。

码字不易,希望可以一键三连,我们下期文章再见!!!


http://www.ppmy.cn/news/1573827.html

相关文章

教育领域的AI革命:个性化学习导师的技术架构与未来展望 (八)

未来展望:教育元宇宙的雏形——重构人类认知边界的数字新大陆 一、技术基座:构建虚实共生的教育基础设施 神经界面革命脑机接口教育套件 斯坦福大学2024年推出的NeuroEdu头盔,通过128通道EEG阵列实现思维捕捉,学生可通过意念操控虚拟实验室设备,实验数据显示: 物理概念理…

Python----数据结构(栈:列表栈,链栈。初始化,入栈,出栈,获取栈长度,判断是否为空,访问栈顶元素)

一、栈 1.1、概念 栈(stack):又名堆栈,它是一种运算受限的线性表,是一种容器,可存入数据元素、访 问元素、删除元素,它的特点在于只能允许在容器的一端(成为栈顶top),进…

知识蒸馏:如何让小模型继承大模型的智慧,提升效率不牺牲效果

我们今天给大家分享一篇知识蒸馏的工作。 我们知道,现如今模型各种各样,效果方面屡创新高。但是,有的时候,效果提升会有效率的牺牲。那么知识蒸馏,就是能够让保证效果的同时,提升效率。这篇文章将给大家来…

GAMES101-现代计算机图形学入门笔记

主讲老师:闫令琪,此处仅做个人笔记使用。如果我的分享对你有帮助,请记得点赞关注不迷路。 课程链接如下:GAMES101-现代计算机图形学入门-闫令琪_哔哩哔哩_bilibili 课程分为四部分:光栅化、几何、光线追踪、模拟 图形…

uniapp录制语音

给大家讲解瞎 录制语音 的功能,这部分主要涉及到以下几个步骤:开始录音、停止录音、播放录音的功能 1.开始录音 (startRecording 函数) 当用户点击 开始录音 按钮时,调用 startRecording 函数开始录音。录音通过 uni.getRecorderManager() …

实验流量统计设计

当我们需要统计实验中每个分支的实际进入次数时,如何设计一个高效、可靠且对业务影响最小的方案,成为了关键。以下是几种常见的流量统计方案的分析与实现设计 目标 不影响实际业务使用,不应该因为汇报错误,导致灰度、甚至实际业…

Qt中使用QPdfWriter类结合QPainter类绘制并输出PDF文件

一.类的介绍 1.QPdfWriter介绍 Qt中提供了一个直接可以处理PDF的类,这就是QPdfWriter类。 (1)PDF文件生成 支持创建新的PDF文件或覆盖已有文件,通过构造函数直接绑定文件路径或QFile对象; 默认生成矢量图形PDF&#…

【DeepSeek 系列】DeepSeekMoE

文章目录 Transformers 中的 MoETransformer语言模型通用的MoE架构 DeepSeekMoE架构细粒度专家分割共享专家隔离负载均衡考虑 模型预训练不同尺寸模型超参数概览DeepSeekMoE 2B训练数据基础设施超参数 DeepSeekMoE 16B训练数据超参数 DeepSeekMoE 16B 的对齐训练数据超参数 总结…