TCP连接的建立和断开过程

318 阅读4分钟

TCP连接的建立和断开过程是网络通信的核心机制,主要通过三次握手(Three-way Handshake)建立连接,通过四次挥手(Four-way Handshake)断开连接。以下是详细说明:


一、TCP连接建立:三次握手

目的:确保通信双方都能正常发送和接收数据,并同步初始序列号(Sequence Number)。

步骤详解

  1. 第一次握手(SYN)

    • 客户端发送一个TCP报文:
      • 标志位SYN=1(表示请求建立连接)
      • 序列号(Seq):随机值 X(例如 Seq = 100)
    • 客户端进入 SYN_SENT 状态。
  2. 第二次握手(SYN + ACK)

    • 服务器收到 SYN 后,回复确认报文:
      • 标志位SYN=1(表示同意建立连接) + ACK=1(确认客户端的SYN)
      • 序列号(Seq):随机值 Y(例如 Seq = 300)
      • 确认号(Ack)X + 1(例如 Ack = 101)
    • 服务器进入 SYN_RCVD 状态。
  3. 第三次握手(ACK)

    • 客户端收到 SYN+ACK 后,发送最终确认报文:
      • 标志位ACK=1
      • 序列号(Seq)X + 1(例如 Seq = 101)
      • 确认号(Ack)Y + 1(例如 Ack = 301)
    • 服务器收到后,双方进入 ESTABLISHED 状态,连接建立成功。

为什么需要三次握手?

  • 两次握手的风险:若客户端的失效连接请求(SYN)延迟到达服务器,服务器会误认为新连接已建立,导致资源浪费。
  • 第三次握手的作用:客户端确认服务器的响应有效,避免历史连接干扰。

二、TCP连接断开:四次挥手

目的:双方确认数据已发送完毕,安全关闭连接。

步骤详解

假设客户端主动发起关闭:

  1. 第一次挥手(FIN)

    • 客户端发送结束报文:
      • 标志位FIN=1(表示请求关闭连接)
      • 序列号(Seq):当前值 P(例如 Seq = 500)
    • 客户端进入 FIN_WAIT_1 状态。
  2. 第二次挥手(ACK)

    • 服务器收到 FIN 后,回复确认报文:
      • 标志位ACK=1
      • 序列号(Seq):当前值 Q(例如 Seq = 700)
      • 确认号(Ack)P + 1(例如 Ack = 501)
    • 服务器进入 CLOSE_WAIT 状态,客户端收到后进入 FIN_WAIT_2 状态。

    注意:此时服务器可能还有未发送完的数据(半关闭状态)。

  3. 第三次挥手(FIN)

    • 服务器完成数据发送后,发送自己的结束报文:
      • 标志位FIN=1 + ACK=1
      • 序列号(Seq)Q + 数据长度(例如 Seq = 750)
      • 确认号(Ack):仍为 P + 1(例如 Ack = 501)
    • 服务器进入 LAST_ACK 状态。
  4. 第四次挥手(ACK)

    • 客户端收到 FIN 后,回复最终确认报文:
      • 标志位ACK=1
      • 序列号(Seq)P + 1(例如 Seq = 501)
      • 确认号(Ack)Seq + 1(例如 Ack = 751)
    • 客户端进入 TIME_WAIT 状态,等待 2MSL(Maximum Segment Lifetime)后关闭。
    • 服务器收到 ACK 后立即关闭连接。

关键问题解析

  1. 为什么需要四次挥手?
    TCP是全双工协议,双方需独立关闭自己的数据通道。

    • 客户端发送 FIN 表示不再发送数据(但仍可接收)。
    • 服务器可能仍需发送剩余数据,故先回复 ACK,再单独发送 FIN
  2. TIME_WAIT状态的作用(等待2MSL):

    • 确保最后一个ACK到达服务器:若服务器未收到ACK,会重发FIN,客户端可重新响应。
    • 避免旧连接的数据包干扰新连接:等待所有网络中的残余数据包消亡(MSL通常为30秒-2分钟)。

三、连接状态变化示意图

客户端                         服务器
  |                              |
  |-------- SYN (Seq=X) -------->|  【三次握手开始】
  |<------- SYN+ACK (Seq=Y, Ack=X+1)|
  |-------- ACK (Ack=Y+1) ------>|  【连接建立】
  |                              |
  |... 数据传输 ...              |
  |                              |
  |-------- FIN (Seq=P) -------->|  【四次挥手开始】
  |<------- ACK (Ack=P+1) -------|  (半关闭)
  |                              |
  |<------- FIN (Seq=Q) ---------|  
  |-------- ACK (Ack=Q+1) ------>|  【连接关闭】
  |(等待2MSL)                    |
  |                              |

四、实际应用注意事项

  1. SYN Flood攻击:攻击者伪造大量SYN请求但不回复ACK,耗尽服务器资源。
    防御:启用 SYN Cookies 或限制半连接数。

  2. 大量TIME_WAIT连接

    • 原因:短连接频繁建立/关闭(如Web服务器)。
    • 解决:调整内核参数(如 net.ipv4.tcp_tw_reuse)或使用连接池。
  3. TCP Keepalive
    长时间空闲的连接可能被中间设备断开,可通过Keepalive探测对方存活状态。


总结

阶段关键动作目的
三次握手SYN → SYN+ACK → ACK同步序列号,确认双向通信能力
四次挥手FIN → ACK → FIN → ACK安全关闭双向数据通道
TIME_WAIT客户端等待2MSL确保最后一个ACK被接收,清理残余数据

理解TCP连接/断开的细节,有助于诊断网络问题(如连接超时、端口占用)及优化高并发服务。