第18章 TCP连接的建立与终止

所属:TCP/IP详解 卷1:协议 来源:TCP/IP详解 卷1:协议

本章介绍TCP连接的建立与终止,包括三次握手、四次挥手、TCP状态机、复位报文等。


18.1 引言

连接管理

TCP连接管理:

  • 建立连接
  • 终止连接
  • 连接状态
  • 各种异常处理

TCP是面向连接的,需要管理连接。


本章讨论的内容

本章讨论的内容:

  • 三次握手(连接建立)
  • 四次挥手(连接终止)
  • TCP状态机
  • 复位报文(RST)
  • 半关闭
  • 同时打开/同时关闭
  • MSS选项

本章介绍TCP连接管理。


18.2 连接建立:三次握手

什么是三次握手

三次握手(Three-way Handshake):

  • 建立TCP连接需要三次交互
  • 双方确认对方的发送和接收能力
  • 同步初始序号

三次握手建立连接。


三次握手的过程

三次握手的过程:

客户端                                服务器
  |                                     |
  | ---------- SYN ----------->        |  1. 客户端发SYN
  |        seq=x                         |     同步,初始序号x
  |                                     |
  | <------- SYN+ACK ---------         |  2. 服务器发SYN+ACK
  |        seq=y, ack=x+1               |     同步自己的,确认客户端的
  |                                     |
  | ---------- ACK ----------->        |  3. 客户端发ACK
  |        seq=x+1, ack=y+1             |     确认服务器的
  |                                     |
  |        连接建立了!                   |

三次握手:SYN → SYN+ACK → ACK。


为什么是三次

为什么是三次,不是两次?

  1. 确认双方的发送和接收能力

    • 客户端发SYN:服务器知道客户端能发,自己能收
    • 服务器发SYN+ACK:客户端知道服务器能收能发,自己能收能发
    • 客户端发ACK:服务器知道客户端能收
  2. 防止旧的连接请求干扰

    • 如果两次就建立
    • 旧的SYN到了服务器
    • 服务器就建立连接了
    • 但客户端根本不想建立
    • 浪费资源
  3. 同步初始序号

    • 双方都要告诉对方自己的初始序号
    • 双方都要确认对方的
    • 三次刚好

三次握手是必要的。


初始序号

初始序号(ISN):

  • 双方各自随机选择
  • 不是从0开始
  • 随时间变化
  • 防止序号回绕和攻击

为什么随机:

  • 安全
  • 防止伪造
  • 防止旧的分组干扰

初始序号是随机的。


MSS选项

MSS选项(Maximum Segment Size):

  • 最大段大小
  • TCP每次发的最大数据量
  • 不包含TCP首部
  • 在SYN段里协商

MSS和MTU的关系:

  • MSS = MTU - IP首部 - TCP首部
  • 以太网MTU=1500
  • MSS = 1500 - 20 - 20 = 1460

为什么协商MSS:

  • 避免分片
  • 提高效率
  • 双方知道对方能收多大的段

MSS在连接建立时协商。


18.3 连接终止:四次挥手

什么是四次挥手

四次挥手(Four-way Handshake):

  • 关闭TCP连接需要四次交互
  • 因为TCP是全双工的
  • 两个方向要分别关闭
  • 每个方向发一个FIN

四次挥手关闭连接。


四次挥手的过程

四次挥手的过程:

客户端                                服务器
  |                                     |
  | ---------- FIN ----------->        |  1. 客户端发FIN
  |        seq=u                         |     我发完了
  |                                     |
  | <---------- ACK ----------         |  2. 服务器发ACK
  |        ack=u+1                       |     知道了
  |                                     |
  |  客户端半关闭了,还能收              |
  |                                     |
  | <---------- FIN ----------         |  3. 服务器发FIN
  |        seq=v                         |     我也发完了
  |                                     |
  | ---------- ACK ----------->        |  4. 客户端发ACK
  |        ack=v+1                       |     知道了
  |                                     |
  |        连接关闭了!                   |

四次挥手:FIN → ACK → FIN → ACK。


为什么是四次

为什么是四次?

  • TCP是全双工的
  • 两个方向独立
  • 每个方向都要单独关闭
  • 一个FIN关闭一个方向
  • 所以需要两个FIN,每个都有ACK
  • 总共四次

为什么三次握手的第二次可以合并:

  • 建立连接时,SYN和ACK可以放一个包里
  • 关闭时,FIN和ACK通常不能合并
  • 因为收到FIN时,可能还有数据没发完
  • 要先ACK,等数据发完了再FIN

因为全双工,所以四次。


半关闭

半关闭(Half-close):

  • 一方发了FIN,进入半关闭状态
  • 不能发了,但还能收
  • 等对方也发FIN了才完全关闭

为什么需要半关闭:

  • 客户端发完了,告诉服务器我发完了
  • 但服务器可能还有数据要发
  • 客户端还可以收
  • 等服务器也发完了再关

半关闭可以收不能发。


18.4 TCP状态机

TCP状态

TCP有很多状态:

状态说明
CLOSED关闭状态,初始
LISTEN监听,等待连接
SYN_SENT发了SYN,等待SYN+ACK
SYN_RCVD收到SYN,发了SYN+ACK,等待ACK
ESTABLISHED连接建立,数据传输
FIN_WAIT_1发了FIN,等待ACK
FIN_WAIT_2收到FIN的ACK,等待对方的FIN
CLOSE_WAIT收到FIN,发了ACK,等待应用关闭
CLOSING双方同时发FIN
LAST_ACK发了FIN,等待最后的ACK
TIME_WAIT收到FIN,发了ACK,等2MSL

TCP有11个状态。


状态转换图

客户端的状态转换(主动打开):

CLOSED → SYN_SENT → ESTABLISHED → FIN_WAIT_1 → FIN_WAIT_2 → TIME_WAIT → CLOSED

服务器的状态转换(被动打开):

CLOSED → LISTEN → SYN_RCVD → ESTABLISHED → CLOSE_WAIT → LAST_ACK → CLOSED

客户端和服务器的状态路径不同。


TIME_WAIT状态

TIME_WAIT状态:

  • 主动关闭的一方最后进入的状态
  • 等待2MSL时间
  • 然后才到CLOSED

MSL:

  • Maximum Segment Lifetime
  • 最长分节生命期
  • 一个TCP分段在网络上最长存活时间
  • 通常是30秒、1分钟、2分钟

为什么需要TIME_WAIT:

  1. 保证最后的ACK能到达

    • 最后一个ACK可能丢了
    • 对方会重传FIN
    • TIME_WAIT期间还能重发ACK
    • 不然对方收不到ACK会一直重传
  2. 让旧的分组消失

    • 防止这个连接的旧分组
    • 干扰下一个同样的连接
    • 等2MSL,旧的都死了

TIME_WAIT等2MSL。


2MSL等待

2MSL等待:

  • TIME_WAIT的时间是2MSL
  • 为什么是2倍?
  • 一个方向最多MSL
  • 两个方向就是2MSL
  • 保证所有旧分组都消失

2MSL是最长的分组存活时间的两倍。


18.5 复位报文

什么是复位报文

复位报文(RST):

  • RST标志位为1的段
  • 复位连接
  • 异常情况下用
  • 不用四次挥手,直接复位

RST直接复位连接。


什么时候发RST

什么时候发RST:

  1. 连接不存在,收到数据

    • 给一个没有的连接发数据
    • 对方回RST
  2. 连接请求被拒绝

    • 端口没开
    • 服务器回RST
  3. 异常关闭连接

    • 不想正常关闭
    • 直接发RST
    • 跳过TIME_WAIT
  4. 半开连接

    • 一方以为连接还在
    • 另一方已经关了
    • 发数据就会收到RST

RST用于各种异常情况。


RST vs FIN

RST vs FIN:

对比项FINRST
用途正常关闭异常复位
过程四次挥手一次就完
数据缓冲区的数据会发完直接丢
状态有序关闭强制关闭
TIME_WAIT有没有

FIN是正常关闭,RST是异常复位。


18.6 同时打开和同时关闭

同时打开

同时打开(Simultaneous Open):

  • 双方同时主动打开
  • 双方同时发SYN
  • 比较少见

过程:

  • 双方都发SYN
  • 双方都收到SYN
  • 双方都发SYN+ACK
  • 双方都收到SYN+ACK
  • 连接建立

状态转换:

  • 两边都是SYN_SENT → SYN_RCVD → ESTABLISHED

同时打开比较少见。


同时关闭

同时关闭(Simultaneous Close):

  • 双方同时主动关闭
  • 双方同时发FIN
  • 也比较少见

过程:

  • 双方都发FIN
  • 双方都收到FIN
  • 双方都发ACK
  • 双方都收到ACK
  • 双方都进入CLOSING
  • 然后TIME_WAIT
  • 最后CLOSED

状态转换:

  • 两边都是FIN_WAIT_1 → CLOSING → TIME_WAIT → CLOSED

同时关闭也比较少见。


18.7 小结

连接建立

  1. 三次握手

    • SYN → SYN+ACK → ACK
    • 三次交互
  2. 为什么三次

    • 确认双方能力
    • 防止旧连接干扰
    • 同步初始序号
  3. 初始序号

    • 随机选择
    • 不是从0开始
  4. MSS选项

    • 最大段大小
    • SYN里协商
    • 避免分片

连接终止

  1. 四次挥手

    • FIN → ACK → FIN → ACK
    • 四次交互
  2. 为什么四次

    • 全双工
    • 两个方向分别关
    • FIN和ACK不能合并
  3. 半关闭

    • 发了FIN,不能发能收
    • 等对方也FIN

TCP状态机

  1. 11个状态

    • CLOSED, LISTEN
    • SYN_SENT, SYN_RCVD
    • ESTABLISHED
    • FIN_WAIT_1, FIN_WAIT_2
    • CLOSE_WAIT, CLOSING
    • LAST_ACK, TIME_WAIT
  2. 客户端路径

    • CLOSED → SYN_SENT → ESTABLISHED → FIN_WAIT_1 → FIN_WAIT_2 → TIME_WAIT → CLOSED
  3. 服务器路径

    • CLOSED → LISTEN → SYN_RCVD → ESTABLISHED → CLOSE_WAIT → LAST_ACK → CLOSED

TIME_WAIT

  1. 什么是TIME_WAIT

    • 主动关闭最后等2MSL
    • 然后才关闭
  2. 为什么需要

    • 保证最后ACK到达
    • 让旧分组消失
  3. 2MSL

    • 最长分节生命期的两倍
    • 保证所有旧分组都死了

复位报文

  1. 什么是RST

    • 复位报文
    • 直接复位连接
  2. 什么时候发

    • 连接不存在
    • 请求被拒绝
    • 异常关闭
    • 半开连接
  3. vs FIN

    • FIN正常关闭
    • RST异常复位

同时打开/关闭

  1. 同时打开

    • 双方同时发SYN
    • 少见
  2. 同时关闭

    • 双方同时发FIN
    • CLOSING状态
    • 少见

关键概念

  1. 三次握手

    • 建立连接
    • SYN, SYN+ACK, ACK
  2. 四次挥手

    • 关闭连接
    • FIN, ACK, FIN, ACK
  3. TIME_WAIT

    • 2MSL等待
    • 两个原因
  4. RST

    • 复位连接
    • 异常情况
  5. 状态机

    • 11个状态
    • 状态转换

TCP传输控制协议