真实面经题目 · 原创解析

为什么 TCP 建立连接需要三次握手?

TCP 三次握手的目的不是单纯通知双方在线,而是让双方确认彼此的发送和接收能力、同步初始序列号、协商连接参数,并避免历史重复连接请求造成错误连接。两次握手无法可靠完成这些目标。

出现于:字节跳动 · 测开

60 秒回答模板

可以按三步解释。第一次握手,客户端发送 SYN 和自己的初始序列号,表示希望建立连接。第二次握手,服务端回复 SYN+ACK,既确认收到了客户端的 SYN,也发送自己的初始序列号。第三次握手,客户端回复 ACK,确认收到了服务端的 SYN。完成后,双方都知道自己的发送能到达对方、自己的接收能收到对方数据,并且双方序列号都已被确认。三次握手还能过滤网络中滞留的旧 SYN,避免服务端仅凭一个过期请求就建立连接并分配资源。握手过程中还会协商 MSS、窗口扩大、SACK、时间戳等 TCP 选项。测试时要覆盖丢包、重传、旧包、半连接队列、SYN flood 和握手超时等场景。

考点 确认双向能力
难度 真实面经高频题
回答目标 讲清机制、边界和追问

深入解析

01

TCP 是双向字节流

TCP 连接建立后是全双工通信,双方都要发送数据,也都要接收数据。因此建立连接时不仅要确认某一方能发出去,还要确认两个方向的序列号和收发能力都可用。三次握手就是为双向可靠传输建立初始状态。

02

第一次握手

客户端发送 SYN,并带上客户端选择的初始序列号。服务端收到后,可以确认客户端到服务端这个方向的报文能到达,也知道后续要从哪个序列号开始确认。但此时客户端还不知道服务端是否收到,也不知道服务端的初始序列号。

03

第二次握手

服务端回复 SYN+ACK,一方面确认客户端的 SYN,另一方面发送自己的初始序列号。客户端收到这一步后,可以确认客户端发送能力、服务端接收能力、服务端发送能力和客户端接收能力都具备。但服务端还不知道客户端是否收到了自己的 SYN。

04

第三次握手

客户端发送 ACK 确认服务端的 SYN。服务端收到后,才知道自己的发送方向也被对方确认,双方序列号同步完成,连接可以进入已建立状态。第三次握手也是避免服务端在不确定对端是否存在时过早确认连接的关键步骤。

05

两次握手的问题

如果只有两次握手,服务端可能在发送 SYN+ACK 后就认为连接建立。网络中的旧 SYN 延迟到达时,服务端可能误建连接并等待一个早已不存在的客户端,造成资源浪费和状态错误。三次握手通过最终 ACK 让服务端得到客户端仍然有效的确认。

易错点

  • 只说三次握手是为了确认双方在线,没有解释序列号和双向收发能力确认。
  • 认为第二次握手后服务端已经完全确认连接,忽略服务端还没收到最终 ACK。
  • 没有提到旧 SYN、重复报文和资源浪费问题,导致两次握手不足的原因说不清。
  • 把三次握手和四次挥手混在一起,错误地用关闭连接逻辑解释建立连接。

面试官追问

为什么不是两次握手?

两次握手后,客户端能确认服务端收到了自己并能回包,但服务端无法确认客户端收到了自己的 SYN。服务端可能因旧 SYN 或丢失的 SYN+ACK 误建连接。

为什么不是四次握手?

第二次握手把服务端的 SYN 和对客户端 SYN 的 ACK 合并到一个报文中,已经能表达两个信息。建立连接时双方都还没有半关闭需求,因此没必要拆成四次。

第三次 ACK 丢失会怎样?

服务端收不到第三次 ACK 会保留半连接状态并重传 SYN+ACK,直到超时放弃。客户端如果已经进入已建立状态,后续发送数据时也会携带确认信息,服务端可据此完成状态推进。

SYN flood 利用了什么弱点?

攻击者大量发送 SYN 后不完成第三次握手,使服务端半连接队列和资源被占用。防御通常包括 SYN cookies、队列调优、限速、清洗和前置负载均衡保护。