🤝 TCP三次握手:客户端和服务器的"初次见面"仪式

35 阅读3分钟

知识点编号:010
难度等级:⭐⭐(必掌握)
面试频率:🔥🔥🔥🔥🔥


🎯 一句话总结

TCP三次握手就像两个陌生人确认对方都能听懂彼此说话,需要三次确认!


🎭 三次握手的三个步骤

第一步:SYN(你好吗?)

客户端发送:SYN=1, seq=x "嘿,我想和你建立连接,我的初始序号是X"

第二步:SYN+ACK(我很好,你呢?)

服务器回复:SYN=1, ACK=1, seq=y, ack=x+1 "好的!我也想建立连接,我的序号是Y,我收到了你的X"

第三步:ACK(我也很好!)

客户端确认:ACK=1, seq=x+1, ack=y+1 "好的,我收到了你的Y,开始通信吧!"


📊 图解

客户端                           服务器
   |                               |
   |  ①SYN seq=100                 |
   |------------------------------>|
   |       (SYN_SENT)              | (SYN_RCVD)
   |                               |
   |  ②SYN+ACK seq=200,ack=101     |
   |<------------------------------|
   |  (ESTABLISHED)                | (ESTABLISHED)
   |                               |
   |  ③ACK seq=101,ack=201         |
   |------------------------------>|
   |                               |
   |    🎉 连接建立成功! 🎉          |
   |<=============================>|

💡 为什么是三次?两次不行吗?

两次握手的问题: 无法防止旧的重复连接请求。

示例场景

1. 客户端发送连接请求A(网络延迟)
2. 客户端超时,重发连接请求B
3. 请求B到达,建立连接,通信完毕,断开
4. 旧请求A终于到达
5. 如果只有两次握手:
   - 服务器认为是新连接,进入等待状态
   - 客户端根本不知道
   - 服务器白白浪费资源!💸
6. 有三次握手:
   - 服务器回复SYN+ACK
   - 客户端不会回复第三次ACK(因为它知道这是旧请求)
   - 服务器超时后释放资源 ✅

🐛 常见面试题

Q1:为什么TCP需要三次握手?

答案:

  1. 确认双方的收发能力都正常
  2. 同步双方的初始序列号
  3. 防止旧的重复连接请求

Q2:第三次握手可以携带数据吗?

答案: 可以!第三次握手时连接已建立,可以携带应用层数据。 但前两次握手不能携带数据(防止SYN Flood攻击)。

Q3:三次握手中,如果第三次ACK丢失了怎么办?

答案:

客户端:认为连接已建立,开始发送数据
服务器:未收到ACK,停留在SYN_RCVD状态
       会重传SYN+ACK包
       如果客户端发送数据,服务器会回复ACK
       然后进入ESTABLISHED状态

💻 Java代码示例

// 客户端:建立连接自动完成三次握手
Socket socket = new Socket("127.0.0.1", 8080);
// 👆 这一行代码内部完成了三次握手!

// 服务器:接受连接自动完成三次握手
ServerSocket serverSocket = new ServerSocket(8080);
Socket clientSocket = serverSocket.accept();
// 👆 accept()方法阻塞直到三次握手完成!

🎓 总结

三次握手是TCP连接建立的基础,记住:

  1. 第一次:SYN(客户端→服务器)
  2. 第二次:SYN+ACK(服务器→客户端)
  3. 第三次:ACK(客户端→服务器)

生活比喻

你:"在吗?"(第一次)
朋友:"在,你呢?"(第二次)
你:"我也在,开始聊吧!"(第三次)

文档创建时间:2025-10-31
作者:AI助手 🤖