TCP的三次握手和四次挥手

79 阅读4分钟

TCP基础入门

1、TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的通信协议,数据在传输前要建立连接,传输完毕后还要断开连接。

2、客户端在收发数据前要使用 connect() 函数和服务器建立连接。建立连接的目的是保证IP地址、端口、物理链路等正确无误,为数据的传输开辟通道。

3、TCP建立连接时要传输三个数据包,俗称三次握手(Three-way Handshaking)

TCP数据报结构

①序号:Seq(Sequence Number)序号占32位,用来标识从计算机A发送到计算机B的数据包的序号,计算机发送数据时对此进行标记。 ②确认号:Ack(Acknowledge Number)确认号占32位,客户端和服务器端都可以发送,Ack = Seq + 1。 ③标志位:每个标志位占用1Bit,共有6个,分别为 URG、ACK、PSH、RST、SYN、FIN,具体含义如下:

URG:紧急指针(urgent pointer)有效。 ACK:确认序号有效。 PSH:接收方应该尽快将这个报文交给应用层。 RST:重置连接。 SYN:建立一个新连接。 FIN:断开一个连接。

以下是对 TCP 三次握手四次挥手的详细解析笔记,涵盖核心流程、状态转换、关键字段作用及常见问题。


一、TCP 三次握手(建立连接)

流程图

Client                               Server
  |                                   |
  |          SYN (seq=x)              |
  | ---------------------------------> |
  |                                   | → 状态:SYN-RECEIVED
  |          SYN-ACK (seq=y, ack=x+1) |
  | <--------------------------------- |
  | ← 状态:SYN-SENT                 |
  |          ACK (ack=y+1)            |
  | ---------------------------------> |
  | ← 状态:ESTABLISHED              | → 状态:ESTABLISHED

步骤详解:

  1. 第一次握手(SYN)

    • Client 发送 SYN=1 报文,随机生成初始序列号 seq=x
    • Client 进入 SYN-SENT 状态。
    • 作用:协商初始序列号,探测 Server 是否可通信。
  2. 第二次握手(SYN-ACK)

    • Server 收到 SYN 后,返回 SYN=1ACK=1,携带自己的初始序列号 seq=y,并确认号 ack=x+1
    • Server 进入 SYN-RECEIVED 状态。
    • 作用:确认 Client 的 SYN,并同步自身初始序列号。
  3. 第三次握手(ACK)

    • Client 发送 ACK=1,确认号 ack=y+1
    • 双方进入 ESTABLISHED 状态,连接建立完成。
    • 作用:确认 Server 的 SYN-ACK,防止历史连接干扰。

二、TCP 四次挥手(终止连接)

流程图

Client                               Server
  |                                   |
  |          FIN (seq=u)              |
  | ---------------------------------> |
  | ← 状态:FIN-WAIT-1              | → 状态:CLOSE-WAIT
  |          ACK (ack=u+1)            |
  | <--------------------------------- |
  | ← 状态:FIN-WAIT-2              |
  |                                   | → 发送剩余数据(若有)
  |          FIN (seq=v, ack=u+1)     |
  | <--------------------------------- |
  | ← 状态:TIME-WAIT               | → 状态:LAST-ACK
  |          ACK (ack=v+1)            |
  | ---------------------------------> |
  | ← 状态:CLOSED                  | → 状态:CLOSED

步骤详解:

  1. 第一次挥手(FIN)

    • Client 发送 FIN=1,携带序列号 seq=u
    • Client 进入 FIN-WAIT-1 状态。
    • 作用:Client 主动关闭连接,不再发送数据。
  2. 第二次挥手(ACK)

    • Server 返回 ACK=1,确认号 ack=u+1
    • Server 进入 CLOSE-WAIT 状态,继续处理未完成的数据。
    • Client 收到 ACK 后进入 FIN-WAIT-2 状态。
  3. 第三次挥手(FIN)

    • Server 处理完数据后,发送 FIN=1,携带序列号 seq=v
    • Server 进入 LAST-ACK 状态。
    • 作用:Server 主动关闭连接。
  4. 第四次挥手(ACK)

    • Client 返回 ACK=1,确认号 ack=v+1
    • Client 进入 TIME-WAIT 状态(等待 2MSL 时间),最终关闭。
    • Server 收到 ACK 后立即关闭。

三、核心问题解析

1. 为什么握手是三次,挥手是四次?

  • 三次握手:Server 的 SYNACK 可合并发送(第二次握手)。
  • 四次挥手:Server 可能仍有数据要发送,需将 ACKFIN 分开发送。

2. TIME-WAIT 状态的作用?

  • 防止旧连接的报文干扰新连接:等待 2MSL(报文最大生存时间)确保网络中残留报文失效。
  • 确保最后一次 ACK 可靠到达:若 Server 未收到 ACK,会重发 FIN。

3. 半关闭状态(CLOSE-WAIT)

  • 当一方发送 FIN 后,另一方可能处于 CLOSE-WAIT 状态继续发送数据,直到发送 FIN。

四、常见问题

Q1:SYN 攻击是什么?

  • 原理:攻击者伪造大量 SYN 请求,耗尽 Server 资源。
  • 防御:启用 SYN Cookie、限制半连接数。

Q2:为什么 Client 需要等待 2MSL?

  • 确保 Server 收到最终 ACK,若未收到,Server 会重发 FIN,Client 可再次响应。

Q3:CLOSED 和 TIME-WAIT 的区别?

  • CLOSED:连接完全关闭。
  • TIME-WAIT:等待期间仍占用端口,防止端口快速复用导致冲突。

五、总结对比表

阶段次数关键字段状态变化核心作用
三次握手3SYN/ACKSYN-SENT → ESTABLISHED建立双向可靠连接
四次挥手4FIN/ACKFIN-WAIT-1 → CLOSED安全终止全双工连接

如果需要结合具体代码或网络抓包分析,可以进一步展开讨论。 REF: