TCP(传输控制协议)作为网络世界中的可靠“通信管家”,其首要职责便是为通信双方制定明确的“沟通”礼仪:在开始对话前必须先建立连接,结束时也要礼貌断开连接,绝不允许“不告而别”。而三次握手,正是 TCP 为双方量身打造的“建立连接”仪式。
TCP的握手仪式:你好 → 收到 → 收到确认
你可能没有意识到,每次打开网页或访问链接的瞬间,你的设备都在 TCP 协议的安排下,与远方的服务器完成了一场严谨的“初次见面仪式”。这场仪式分为三个关键步骤。
第一步:客户端发起连接请求(SYN)
要与远方的服务器建立连接,首先需要确认两件事:对方是否在线以及是否愿意沟通。为此,客户端会主动发送一个“打招呼”的数据包,在 TCP 中专门称为 SYN 包。

图1:客户端发送SYN包示意图
这个 SYN 包相当于一次试探性的喊话:“你好!我是客户端A,想与你建立连接。如果收到,请回复我!”
当然,这个包不只包含问候,其 TCP 头部承载着关键信息。

图2:TCP头部SYN包结构
除了源端口、目标端口等基础字段,最核心的是以下两类信息:
- SYN=1:这是一个明确的标志位,告知对方此数据包的目的是发起连接请求。
- seq=x:这是客户端为本次通信生成的初始序列号(ISN)。后续发送的每一个数据字节都会按 x+1, x+2 的顺序依次编号,以确保数据能按序被接收。
第二步:服务器回应请求(SYN+ACK)
当服务器收到客户端发来的 SYN 包后,如果它在线且愿意建立连接,便会回复一个 SYN+ACK 包。

图3:服务器回复SYN+ACK包示意图
这个包犹如热情的回应:“你好客户端A!我是服务器B,我收到了你的连接请求。我这边也准备好和你通信了!”

图4:TCP头部SYN+ACK包结构
这个双重礼包结合了两个关键动作:
- 确认收到(ACK):通过设置
ACK=1 和 确认号 ack=x+1,明确告诉客户端:“你的连接请求(序号x)我已收到,我期待接收你从 x+1 开始的数据”。
- 发起同步(SYN):通过设置
SYN=1 和 服务器的初始序列号 seq=y,相当于对客户端说:“这是我后续发送数据使用的起始编号,请你按此规则接收”。
这里引出一个核心问题:为什么通信双方都需要生成一个随机的初始序列号?
主要原因有两个:
-
解决双向通信的秩序问题
TCP 连接是全双工的,就像一条双向车道,客户端和服务器会同时向对方发送数据。双方使用独立的序列号空间(客户端用 seq=x 系列,服务器用 seq=y 系列),可以清晰区分两个方向的数据流,避免混淆。

图5:双向数据流序列号示意
-
防止历史旧数据包干扰
初始序列号是随机生成的,而非总是从0或1开始。这主要是为了防止网络中延迟的、属于上一次连接的旧数据包误入当前会话。由于新旧会话的序列号范围完全不匹配,这些“幽灵包”会被直接丢弃,保证了当前连接的纯净性。

图6:随机序列号防止旧包干扰示意
通过交换初始序列号,双方就像拿到了“双向对话手册”,为后续有序的数据传输奠定了基础。
第三步:客户端最终确认(ACK)
至此,服务器已发出回应,但它心里仍存疑虑:客户端真的收到我的 SYN+ACK 包了吗?万一这个包在网络中丢失了怎么办?
这时,需要客户端完成最后一步收尾工作:发送一个 ACK 包。

图7:客户端发送ACK确认包
这个包相当于最终拍板:“服务器B!你的回复我已收到,现在我们正式建立连接,可以开始传输数据了!”

图8:TCP头部ACK包结构
这个 ACK 包包含两个关键信息:
- ACK=1 与 ack=y+1:表明客户端不仅收到了服务器的“自我介绍”(序号y),并且确认“已准备好接收服务器从 y+1 开始的数据”。
- seq=x+1:因为第一次握手时发送的 SYN 包已消耗了序号 x,所以本次报文的序号顺延为 x+1。
至此,双方通过 “SYN → SYN+ACK → ACK” 三次信息交换,完成了所有必要的确认:
“我能听到你,你也能听到我,并且我们都清楚接下来如何为数据编号。”
这条稳定的全双工数据传输通道就此建立。后续所有的网页浏览、消息发送都将通过这条通道安全、有序地进行。
TCP握手次数:为何两次不够,四次多余?
既然握手的目的是建立可靠连接,那么为何次数偏偏是三次?两次或四次是否可行?
两次握手的隐患:遭遇“幽灵连接”
如果只进行两次握手(SYN → SYN+ACK),服务器在发出 SYN+ACK 后便认为连接已建立,会立即为此连接分配资源。但这存在一个致命漏洞:服务器无法确认客户端是否真的收到了自己的回应。
考虑一个场景:客户端发出的 SYN 包因网络拥堵严重延迟。服务器在很久后才收到这个包,并回复 SYN+ACK。然而,客户端早已因超时关闭了这个连接请求,不会处理这个迟到的回复。

图9:延迟SYN包导致服务器空等
此时,服务器却会一直等待这个“不存在的连接”发送数据,并为其保留资源。如果网络中有大量这种“迟到的 SYN 包”,就会产生一群“幽灵连接”,逐渐耗尽服务器资源,导致其无法响应正常的新请求,即 SYN Flood 攻击 的雏形。

图10:幽灵连接占用服务器资源
第三次握手(客户端的ACK)正是给服务器的“定心丸”。只有在收到这个最终确认后,服务器才会正式分配连接资源。那些未收到ACK的“幽灵邀约”,服务器会在超时后自动清理,有效避免了资源浪费。
四次握手:画蛇添足
既然两次不安全,那四次握手(在三次基础上,让服务器再发一个ACK确认客户端的ACK)是否更稳妥?答案是完全没必要。
三次握手已经精准、无遗漏地完成了 双方初始序列号的同步 和 双向连接建立的确认。增加第四次握手,只是让服务器重复确认“我收到了你的确认”,如同见面时已经互相问好,却还要追问一句“你确定知道我到了吗?”,纯属多余。

图11:四次握手冗余示意
这种冗余不仅会增加网络开销,还会延长连接建立时间,降低效率。
因此,三次握手是 TCP 协议在确保连接可靠性和追求通信效率之间找到的完美平衡点。
总结:可靠通信的基石
TCP 的三次握手,是网络世界一次简洁而严谨的信任建立仪式。它通过三次信息交换,为两台陌生的设备搭建起可靠的通信桥梁,协商好数据传输的秩序,并有效防御了历史数据包干扰及资源耗尽攻击,为上层应用提供了稳定的数据传输服务。这正是互联网可靠性的核心基石之一。
本文由云栈社区整理发布。