Skip to content

408

计算机网络

CN-05-04 TCP连接管理(三次握手/四次挥手)


一、定位信息

  • 圈层:核心层
  • 前置知识:需要掌握TCP报文段格式(尤其是SYN、ACK、FIN标志位和序号、确认号字段),理解面向连接通信的含义
  • 知识网络位置:TCP连接管理是TCP协议的核心机制之一,是可靠传输、流量控制、拥塞控制的前提——只有先建立连接,后续机制才能发挥作用
  • 考点热度等级H级(高频重点)——几乎每年必考,选择题和综合题均有出现,特别是三次握手的细节和四次挥手的过程

二、知识点讲解

2.1 连接管理概述

TCP是面向连接的协议,每次通信前必须先建立连接,通信结束后释放连接。TCP连接的管理分为三个阶段:建立连接(三次握手)数据传输释放连接(四次挥手)

TCP连接的端点称为套接字(Socket)插口,一个TCP连接由通信双方的套接字唯一标识:{(源IP,源端口),(目的IP,目的端口)}

2.2 三次握手(Three-Way Handshake)

TCP建立连接采用三次握手过程,目的是同步双方的初始序号(ISN)并协商连接参数。

详细过程(设客户端A主动发起连接,服务器B被动等待):

第一次握手:客户端 → 服务器

  • 客户端发送一个TCP报文段,其中:
    • SYN = 1,ACK = 0
    • 序号(seq)= x(客户端随机选择的初始序号)
    • 数据部分为空
  • 客户端进入 SYN_SENT 状态
  • 含义:A向B请求建立连接,"我的初始序号是x"

第二次握手:服务器 → 客户端

  • 服务器收到SYN报文段后,回复一个TCP报文段,其中:
    • SYN = 1,ACK = 1
    • 序号(seq)= y(服务器随机选择的初始序号)
    • 确认号(ack)= x + 1
    • 数据部分为空
  • 服务器进入 SYN_RCVD 状态
  • 含义:B同意建立连接,"我的初始序号是y,我已经收到了你的x"

第三次握手:客户端 → 服务器

  • 客户端收到SYN+ACK报文段后,回复一个TCP报文段,其中:
    • SYN = 0,ACK = 1
    • 序号(seq)= x + 1
    • 确认号(ack)= y + 1
    • 可以携带数据
  • 客户端进入 ESTABLISHED 状态
  • 服务器收到后也进入 ESTABLISHED 状态
  • 含义:A确认收到B的回复,"我确认你的y,连接建立"
    客户端A                                    服务器B
      |                                          |
      |  ---- SYN=1, seq=x ----------------->    |  第一次握手
      |      (SYN_SENT)                          |  (SYN_RCVD)
      |                                          |
      |  <-- SYN=1, ACK=1, seq=y, ack=x+1 ---   |  第二次握手
      |                                          |
      |  ---- ACK=1, seq=x+1, ack=y+1 ------->  |  第三次握手
      |      (ESTABLISHED)                       |  (ESTABLISHED)
      |                                          |

2.3 为什么需要第三次握手?

这是408的高频考点。第三次握手的必要性在于防止失效的连接请求到达服务器

假设只有两次握手:如果客户端A发送的第一个SYN报文段因网络延迟没有丢失,而是在某个中间节点滞留了很久。A超时后重发SYN并成功建立连接、完成数据传输、释放连接。之后,之前滞留的那个旧SYN报文段突然到达服务器B,B误以为是新的连接请求,于是回复SYN+ACK并分配资源等待数据——但A并没有发起新连接,不会回复数据,导致B白白浪费资源。

有了第三次握手,B在收到旧SYN后回复SYN+ACK,但A不会对这个旧连接回复ACK(因为A知道这不是自己发起的新连接),B收不到第三次握手的ACK就不会真正建立连接。

2.4 四次挥手(Four-Way Handshake)

TCP释放连接采用四次挥手过程,因为TCP连接是全双工的,每个方向需要单独关闭。

详细过程(设客户端A主动关闭):

第一次挥手:A → B

  • A发送一个TCP报文段,其中:
    • FIN = 1,ACK = 1
    • 序号 = u(A已发送的最后一个字节的序号+1)
  • A进入 FIN_WAIT_1 状态
  • 含义:A没有数据要发了,请求关闭A→B方向的连接

第二次挥手:B → A

  • B收到FIN后,回复一个TCP报文段,其中:
    • ACK = 1
    • 确认号 = u + 1
    • 序号 = v
  • B进入 CLOSE_WAIT 状态
  • A收到后进入 FIN_WAIT_2 状态
  • 含义:B确认收到A的关闭请求,但B可能还有数据要发给A

第三次挥手:B → A

  • B发送完剩余数据后,发送一个TCP报文段,其中:
    • FIN = 1,ACK = 1
    • 序号 = w(注意:w可能不等于v+1,因为B在CLOSE_WAIT期间可能又发了数据)
    • 确认号 = u + 1
  • B进入 LAST_ACK 状态
  • 含义:B也没有数据要发了,请求关闭B→A方向的连接

第四次挥手:A → B

  • A收到B的FIN后,回复一个TCP报文段,其中:
    • ACK = 1
    • 确认号 = w + 1
    • 序号 = u + 1
  • A进入 TIME_WAIT 状态
  • B收到后进入 CLOSED 状态
  • A等待2MSL(Maximum Segment Lifetime,最大报文段寿命)后进入CLOSED状态
    客户端A                                    服务器B
      |                                          |
      |  ---- FIN=1, ACK=1, seq=u ------------>  |  第一次挥手
      |      (FIN_WAIT_1)                        |
      |                                          |
      |  <-- ACK=1, ack=u+1, seq=v ----------   |  第二次挥手
      |      (FIN_WAIT_2)                        |  (CLOSE_WAIT)
      |                                          |
      |  <-- FIN=1, ACK=1, seq=w, ack=u+1 ---   |  第三次挥手
      |                                          |  (LAST_ACK)
      |  ---- ACK=1, ack=w+1, seq=u+1 --------> |  第四次挥手
      |      (TIME_WAIT)                         |  (CLOSED)
      |                                          |
      |  [等待2MSL]                               |
      |      (CLOSED)                            |

2.5 TIME_WAIT状态与2MSL

客户端在发送完最后一个ACK后进入TIME_WAIT状态,需要等待2MSL(两倍的最大报文段寿命)才真正关闭。等待2MSL的原因有两个:

  1. 确保最后一个ACK能到达B:如果B收不到最后一个ACK,会重发FIN。A在TIME_WAIT期间收到重发的FIN后可以重新发送ACK。2MSL的时间足够让重发的FIN到达A并让A的ACK到达B。

  2. 让旧连接的报文段过期:等待2MSL可以确保本次连接的所有报文段在网络中消失,防止它们影响新建立的同一连接。

2.6 TCP连接状态总结

状态含义所在阶段
CLOSED关闭状态,无连接初始/最终状态
LISTEN监听状态,等待客户端连接服务器端
SYN_SENT已发送SYN,等待对方回复客户端第一次握手后
SYN_RCVD已收到SYN,已回复SYN+ACK服务器第二次握手后
ESTABLISHED连接已建立,可传输数据双方第三次握手后
FIN_WAIT_1已发送FIN,等待确认客户端第一次挥手后
CLOSE_WAIT收到FIN,等待应用层关闭服务器第二次挥手后
FIN_WAIT_2已收到FIN的确认,等待对方FIN客户端收到第二次挥手后
LAST_ACK已发送FIN,等待最后确认服务器第三次挥手后
TIME_WAIT已发送最后ACK,等待2MSL客户端第四次挥手后

三、记忆与理解辅助

  1. 三次握手口诀:"一SYN,二SYN+ACK,三ACK"——第一次发SYN请求,第二次回SYN+ACK同意,第三次发ACK确认。记住第三次ACK可以携带数据。

  2. 四次挥手口诀:"一FIN,二ACK,三FIN,四ACK"——因为全双工,每方向各需要一次FIN+ACK,共四次。中间的ACK和FIN可能间隔很长时间(B还有数据要发)。

  3. 状态记忆法:三次握手状态序列——CLOSED→SYN_SENT→ESTABLISHED(客户端),CLOSED→LISTEN→SYN_RCVD→ESTABLISHED(服务器)。四次挥手——FIN_WAIT_1→FIN_WAIT_2→TIME_WAIT→CLOSED(主动方),CLOSE_WAIT→LAST_ACK→CLOSED(被动方)。

  4. 对比表:三次握手 vs 四次挥手

对比项三次握手四次挥手
目的建立连接,同步序号释放连接,双向各关闭一次
标志位SYN、ACKFIN、ACK
报文段数3个4个(正常情况)
是否可携带数据第三次可以通常不携带
特殊状态SYN_RCVDTIME_WAIT、CLOSE_WAIT
核心问题为什么不是两次?为什么不是三次?

四、例题与精解

例题1(基础巩固)

题目:在TCP三次握手中,第二次握手报文段的标志位为( ),确认号的值等于( )。

A. SYN=1, ACK=1;客户端初始序号+1

B. SYN=1, ACK=0;服务器初始序号+1

C. SYN=1, ACK=1;服务器初始序号+1

D. FIN=1, ACK=1;客户端初始序号+1

命题意图:考查三次握手过程中第二次握手报文段的具体内容。

精解

  1. 审题分析:需要回忆第二次握手中服务器回复的报文段的标志位和确认号。

  2. 解题思路:第二次握手是服务器对客户端SYN的回应,需要同时携带服务器自己的SYN(同步)和对客户端SYN的ACK(确认)。

  3. 完整步骤

    • 第一次握手:客户端发SYN=1, seq=x
    • 第二次握手:服务器回复SYN=1, ACK=1, seq=y, ack=x+1
    • 确认号ack=x+1,即客户端初始序号+1
    • 第三次握手:客户端回复ACK=1, seq=x+1, ack=y+1
  4. 方法反思:第二次握手是最"忙"的——既要发SYN又要发ACK,是唯一一个同时有两个标志位置1的握手报文段。

答案:A


例题2(中等提升)

题目:假设TCP连接建立过程中,客户端选择的初始序号为100,服务器选择的初始序号为300。若客户端随后发送了一个数据长度为200字节的报文段,服务器正确接收后回复确认,则该确认报文段的确认号为( )。之后客户端又发送了一个数据长度为150字节的报文段,但该报文段丢失,随后客户端又发送了一个数据长度为100字节的报文段,服务器正确接收后回复确认,则该确认报文段的确认号为( )。

A. 300, 450

B. 300, 400

C. 300, 300

D. 301, 450

命题意图:考查序号和确认号的计算,以及累积确认机制。

精解

  1. 审题分析:需要逐步计算每个报文段的序号和确认号,注意TCP的累积确认机制。

  2. 解题思路

    • 客户端初始序号ISN=100(注意:三次握手消耗1个序号,所以SYN后客户端的"下一个序号"为101)
    • 但题目问的是数据传输阶段,我们按简化处理——三次握手后客户端的seq=101(SYN消耗了序号100)
    • 实际上,在考研中通常简化处理:SYN报文段seq=x,第三次握手后客户端从seq=x+1开始发送数据
  3. 完整步骤

    • 第一个数据报文段:客户端发送seq=101,数据长度=200,覆盖字节101~300
    • 服务器正确接收,期望收到的下一个字节为301,所以回复确认号=300+1=301

    等等,需要更仔细。客户端初始序号100:

    • 第一次握手:SYN, seq=100(SYN消耗序号100)
    • 第三次握手后,客户端从seq=101开始发数据
    • 第一个数据报文段:seq=101,长度200,覆盖101~300
    • 服务器确认号 = 300 + 1 = 301

    但选项中没有301+450的组合(D选项是301,450),让我重新审视。

    实际上考研中常见的简化:ISN=x,数据从seq=x开始(不考虑SYN消耗的序号),或者确认号=序号+数据长度(不加1)。

    按考研常见简化:

    • 第一个数据报文段:seq=100,长度200,覆盖100~299
    • 确认号 = 299 + 1 = 300 ✓
    • 第二个数据报文段(丢失):seq=300,长度150
    • 第三个数据报文段:seq=450,长度100
    • 服务器收到第三个,但第二个丢失,采用累积确认,确认号仍为300(期望收到300起的数据)

    所以答案:第一个确认号=300,第二个确认号=300。

    答案为C。

  4. 方法反思:累积确认是TCP的重要机制——如果中间有报文段丢失,后续确认号不会更新,始终指向丢失报文段的起始位置。这是SACK(选择确认)机制被引入的原因。

答案:C


五、考情分析

  • 考查频次:近5年408真题中TCP连接管理相关题目每年必考,约5~10次
  • 常见题型:选择题(状态序列、标志位、序号计算)和综合题(完整描述连接建立/释放过程)
  • 分值占比:4~10分,是传输层分值最高的考点之一
  • 命题趋势:近年倾向于考查细节理解——如"为什么需要第三次握手""TIME_WAIT的作用""SYN洪泛攻击的原理"等深层次问题,而非简单的状态记忆
  • 基于大纲与命题规律推测

六、易错点提醒

  1. 错误表现:认为第三次握手不能携带数据

    • 错误原因:前两次握手确实不能携带数据(SYN=1的报文段通常无数据),误以为第三次也不行
    • 正确理解/做法:第三次握手的报文段可以携带数据。因为此时双方都已确认了对方的接收能力,可以立即开始传输数据。
  2. 错误表现:将CLOSE_WAIT和TIME_WAIT搞混

    • 错误原因:两个状态都与"关闭"相关,名字相似
    • 正确理解/做法:CLOSE_WAIT是被动关闭方(收到FIN的一方)的状态,表示"我在等应用层把数据发完再关"。TIME_WAIT是主动关闭方(发最后ACK的一方)的状态,表示"我在等2MSL确保对方收到我的ACK"。
  3. 错误表现:认为四次挥手的中间两次可以合并为一次

    • 错误原因:看到某些教材说"有时候三次就够了"
    • 正确理解/做法:当B收到A的FIN时,如果B恰好没有数据要发送,B可以将第二次挥手(ACK)和第三次挥手(FIN)合并为一个报文段,变成"三次挥手"。但这是特例,正常情况下必须四次。
  4. 错误表现:忽略SYN和FIN消耗序号

    • 错误原因:SYN和FIN报文段可能没有数据部分,误以为不消耗序号
    • 正确理解/做法:SYN报文段和FIN报文段各消耗一个序号。例如SYN的seq=100,则下一个报文段的seq=101(而非100)。

七、来源标注

  • 依据2026考研统考大纲·计算机网络部分
  • 依据《计算机网络(第8版)》谢希仁版
  • 依据RFC 793 - Transmission Control Protocol

考研全科复习资料 - 基于2026考研统考大纲