为什么TCP是三次握手?

为什么TCP是三次握手?

TCP 三次握手的本质,是在不可靠的 IP 信道上,以最小的通信开销,完成两个核心目标:

  1. 确认通信双方全双工的发送、接收能力均正常;
  2. 同步双方的初始序列号 ISN,为后续的可靠传输、按序交付、重传机制奠基,同时规避历史失效连接导致的服务端资源浪费。

两次握手无法解决核心缺陷,四次握手则冗余无必要。

标准三次握手极简流程

TCP 是面向连接的可靠全双工传输协议,连接建立的三次握手由 RFC 793 标准定义:

  1. 第一次握手(客户端→服务端 SYN) :客户端发送同步报文,携带自身初始序列号ISN(c),进入SYN_SENT状态,发起连接请求。
  2. 第二次握手(服务端→客户端 SYN+ACK) :服务端收到 SYN 后,回复同步 + 确认报文,携带自身初始序列号ISN(s),同时确认号为ISN(c)+1,进入SYN_RCVD状态。
  3. 第三次握手(客户端→服务端 ACK) :客户端收到 SYN+ACK 后,回复确认报文,确认号为ISN(s)+1,进入ESTABLISHED状态;服务端收到该 ACK 后,也进入ESTABLISHED状态,全双工连接正式建立。

为什么必须是三次,两次握手有致命缺陷

两次握手无法完成双向收发能力的全量确认

全双工可靠传输的前提,是双方都能确认对方的收发能力正常:

  • 第一次握手后,服务端仅能确认:客户端的发送能力、服务端的接收能力正常;
  • 第二次握手后,客户端能确认双方收发能力均正常,但服务端完全无法验证自己的发送能力是否正常,也无法确认客户端的接收能力是否正常。

若仅两次握手就建立连接,服务端会单方面认为连接就绪并开始发送数据。如果客户端根本没收到服务端的 SYN+ACK 报文,会完全无视后续数据,不仅传输无效,还会持续占用服务端资源。

两次握手无法完成双向 ISN 同步,失去可靠传输的核心基础

TCP 的按序交付、重复报文去重、丢包重传、流量控制,完全依赖字节级的序列号实现。初始序列号 ISN 是动态随机生成的(防止被预测、规避历史报文干扰),必须让双方都确认对方已收到自己的 ISN。

两次握手场景下,客户端能确认服务端收到了自己的 ISN,但服务端无法确认客户端是否收到了自己的 ISN。后续服务端基于ISN(s)发送的数据包,客户端若未收到 ISN,将无法正确校验和确认,直接导致传输不可靠。

两次握手无法抵御历史失效连接,极易造成服务端资源耗尽

这是 TCP 设计最核心的考量之一。网络环境不可靠,客户端发送的 SYN 可能因网络拥堵长时间滞留,客户端超时重发 SYN 并完成传输、断开连接后,滞留的旧 SYN 才到达服务端。

  • 两次握手:服务端收到历史失效 SYN 后,会直接建立连接、分配完整的传输控制块(TCB)资源,而客户端无连接意图,不会发送任何数据,服务端资源会被大量无效连接占用,极易被 SYN 洪水攻击打垮。
  • 三次握手:服务端收到 SYN 后,仅将连接放入半连接队列,不分配完整资源;只有收到客户端的第三次 ACK,才会正式建立连接。对于历史失效 SYN,客户端不会回复 ACK,服务端会超时释放半连接资源,从根源上规避无效资源占用。

为什么四次握手完全没必要

全双工通信的双向同步 + 双向确认,无需拆分为四次。

服务端的SYN(同步自身 ISN)和 ACK(确认客户端的 SYN) 可以合并在同一个报文段中发送,无需拆分两次。

若强行拆分为四次(客户端 SYN→服务端 ACK→服务端 SYN→客户端 ACK),会额外增加一次网络交互,无端增加连接建立延迟、浪费带宽,完全没有必要。

三次握手已经能完成所有核心目标,是兼顾可靠性和效率的最优解。

相关推荐
计算机就业还在扩大10 小时前
第2期-cmp.Ordered+类型推断+刻意未支持的特性
后端·面试·golang
考研保研资料分享10 小时前
2023行政管理跨保华中师大政治学:五场考核、项目追问与择校
面试
王中阳Go18 小时前
两个入口答案不一致先别调模型:6 行入口口径对账表(附脚本)
人工智能·后端·python·大语言模型·1024程序员节
砺星Leetx19 小时前
工业总线选型与对接实战:PROFINET、EtherCAT、EtherNet/IP、PROFIBUS、Modbus-TCP 与 CC-Link
网络·网络协议·tcp/ip·控制器·国产拧紧系统
考研保研资料分享19 小时前
中国人民大学英语笔译保研面经:五校考核、视译口译与择校复盘
面试
码事漫谈20 小时前
消除AI幻觉,普通人能做的五件事
后端
古希腊掌管代码的神THU21 小时前
为什么DPO中chosen/rejected概率同时下降?
人工智能·深度学习·机器学习·自然语言处理·面试
金銀銅鐵21 小时前
[Java] 用 GUI 展示 EnumSet 增减元素时的内部变化(下)
java·后端·ai编程
Mk598781 天前
给 Agent 装上对话框 —— AgentScope-Java 接入 Spring Boot 与 SSE 流式实战
后端
付威20231 天前
从 Loop 到 Runtime:rpi Agent Loop 与 Cordis 的边界、取舍与组合
后端