TCP 三次握手与四次挥手(图解)
图解 TCP 三次握手建立连接、四次挥手断开连接的完整过程,深入理解 SYN/ACK/FIN 的作用。
TCP 三次握手与四次挥手(图解) TCP 是面向连接、可靠的传输协议。理解三次握手和四次挥手,是面试必考题。 一、为什么需要握手? TCP 是 面向连接 的协议,通信前必须建立连接,确认双方的发送和接收能力正常。 二、三次握手(建立连接) 详细步骤 第一次握手 :客户端发送 SYN 报文 SYN = 1(建立连接标志) seq = x(随机初始序列号) 客户端进入 状态 第二次握手 :服务器收到 SYN,回复 SYN+ACK SYN = 1, ACK = 1 seq = y(服务器随机序列号) ack = x + 1(确认客户端的 SYN) 服务器进入 状态 第三次握手 :客户端收到 SYN+ACK,回复 ACK ACK = 1 seq = x + 1 ack = y + 1 双方都进入 状态 为什么是三次?两次不行吗? 核心原因 :防止已失效的连接请求到达服务器,造成资源浪费。 假设只有两次握手: 三次握手可以避免 :客户端收到 ACK 后还可以判断这个连接是否真的需要。 三、四次挥手(断开连接) 详细步骤 第一次挥手 :客户端发送 FIN FIN = 1, seq = u 客户端进入 ,表示没有数据要发送了 第二次挥手 :服务器回复 ACK ACK = 1, ack = u + 1 服务器进入 客户端进入 第三次挥手 :服务器发送 FIN FIN = 1, seq = w 服务器进入 第四次挥手 :客户端回复 ACK ACK = 1, ack = w + 1 客户端进入 ,等待 2MSL 后 服务器收到 ACK 后 为什么挥手是四次? 因为 TCP 是 全双工 的: 客户端发 FIN 表示「我没数据发了」 但服务器可能还有数据要发,所以 ACK 和 FIN 要 分开发 等服务器数据发完,再发 FIN 为什么 TIME WAIT 要等 2MSL? MSL(Maximum Segment Lifetime) :报文最大生存时间。 两个原因: 1. 保证最后的 ACK 到达 :如果服务器没收到 ACK,会重发 FIN,客户端还能再发一次 ACK 2. 让本次连接的所有报文消失 :防止延迟报文影响新连接 四、状态机总览 五、常见面试题 Q1:三次握手可以携带数据吗? 第一次和第二次不行(防止 SYN 洪泛攻击), 第三次可以携带数据 。 Q2:SYN 洪泛攻击是什么?怎么防御? 攻击者伪造大量 SYN 请求,服务器分配资源等待第三次握手,最终耗尽资源。 防御 : SYN Cookie:服务器不分配资源,用加密 Cookie 验证 限制半连接队列大小 防火墙过滤 Q3:连接队列满了会怎样? Linux 有两个队列: syn queue (半连接):收到 SYN,等待 ACK accept queue (全连接):完成握手,等待应用 accept 队列满时,新的连接请求会被丢弃或回 RST。 Q4:已经建立的连接,断电会怎样? TCP 没有机制感知断电。如果长时间无数据,可以开启 KeepAlive (默认 2 小时)。 应用层一般会自己实现心跳。 六、抓包实战 七、小结 | 阶段 | 步骤 | 关键标志 | | | | | | 建立连接 | 3 次握手 | SYN, SYN+ACK, ACK | | 数据传输 | 双向流 | seq, ack | | 断开连接 | 4 次挥手 | FIN, ACK, FIN, ACK | 记住小宇宙的口诀: 三次握手 :确认双方的发送和接收能力 四次挥手 :全双工,要分别关闭两个方向 TIME WAIT 2MSL :保证 ACK 到达 + 报文消失