计算机网络基础 - TCPIP通讯流程

分类: 操作系统

三次握手/四次挥手

为了保证传输的可靠性,TCP 在传输数据之前需要建立连接(三次握手),在传输结束后需要断开连接(四次挥手)。

第一阶段:三次握手 (Three-Way Handshake) —— 建立连接

1. 第一次握手 (SYN)

  • 动作: 客户端发送一个带有 SYN (Synchronize) 标志的数据包给服务端。
  • 内容: 客户端随机生成一个初始序列号 $seq = x$。
  • 状态变化: 客户端进入 SYN_SENT 状态。
  • 含义: “你好,我想建立连接,我的初始序列号是 $x$。”

2. 第二次握手 (SYN + ACK)

  • 动作: 服务端收到 SYN 包后,必须确认客户的 SYN。服务端发送一个带有 SYNACK (Acknowledgment) 标志的数据包。
  • 内容:
  • 确认号 $ack = x + 1$ (表示收到了 $x$,期待下一个是 $x+1$)。
  • 服务端也随机生成自己的初始序列号 $seq = y$。
  • 状态变化: 服务端进入 SYN_RCVD 状态。
  • 含义: “收到了,我同意你的连接请求。同时我也想建立连接,我的初始序列号是 $y$。”

3. 第三次握手 (ACK)

  • 动作: 客户端收到服务端的 SYN+ACK 包,向服务端发送一个 ACK 包。
  • 内容:
  • 序列号 $seq = x + 1$。
  • 确认号 $ack = y + 1$ (表示收到了 $y$,期待下一个是 $y+1$)。
  • 状态变化: 客户端发送后进入 ESTABLISHED 状态,服务端收到后也进入 ESTABLISHED 状态。
  • 含义: “收到你的确认了,连接建立成功,我们可以开始发数据了。”

第二阶段:数据传输

连接建立后,双方就可以通过这个通道双向传输数据了。此时 TCP 会利用滑动窗口、重传机制等保证数据的有序和完整。


第三阶段:四次挥手 (Four-Way Handshake) —— 断开连接

由于 TCP 连接是全双工(Full-Duplex)的,即数据在两个方向上可以同时传输,因此每个方向的关闭都需要单独进行。这意味着断开连接需要四个步骤。

假设客户端(Client)主动发起关闭请求:

1. 第一次挥手 (FIN)

  • 动作: 客户端发送一个 FIN (Finish) 标志的数据包。
  • 含义: “我没有数据要发给你了,我要断开我这边的发送通道。”
  • 状态: 客户端进入 FIN_WAIT_1

2. 第二次挥手 (ACK)

  • 动作: 服务端收到 FIN,回传一个 ACK 包。
  • 含义: “知道了,我同意你断开。但我可能还有数据没发完,你先等等。”
  • 状态:
  • 服务端进入 CLOSE_WAIT(等待关闭)。
  • 客户端收到 ACK 后进入 FIN_WAIT_2
  • 关键点: 此时处于半关闭状态。客户端不能发数据了,但服务端如果还有数据没发完,可以继续发,客户端依然要接收。

3. 第三次挥手 (FIN)

  • 动作: 等服务端所有数据都发完了,它会发送一个 FIN 包给客户端。
  • 含义: “好了,我也发完了,现在我也要断开连接。”
  • 状态: 服务端进入 LAST_ACK

4. 第四次挥手 (ACK)

  • 动作: 客户端收到 FIN,回传一个 ACK 包。
  • 含义: “好的,收到了,再见。”
  • 状态:
  • 客户端进入 TIME_WAIT 状态(注意:不是立即关闭)。
  • 服务端收到 ACK 后,彻底关闭连接,进入 CLOSED

三次握手的意义

1. 第一次握手 (Client 发送 SYN)

核心目的:发起连接 & 同步客户端序列号

  • 同步序列号 (ISN): 客户端告诉服务端:“我打算发数据了,我的初始序号是 $x$。”(这是为了解决网络包乱序问题)。
  • 能力验证(服务端视角):
  • 服务端收到后,确认了 客户端的发送能力 是正常的。
  • 服务端收到后,确认了 服务端的接收能力 是正常的。

2. 第二次握手 (Server 回复 SYN + ACK)

核心目的:确认收到、发起反向连接 & 同步服务端序列号

  • 确认收到: 告诉客户端:“你的请求我收到了,我同意建立连接。”
  • 同步序列号 (ISN): 服务端告诉客户端:“我也要发数据,我的初始序号是 $y$。”
  • 能力验证(客户端视角)—— 这一步最关键:
  • 客户端收到后,确认了 自己的发送能力 正常(因为对方收到了)。
  • 客户端收到后,确认了 自己的接收能力 正常(因为收到了回信)。
  • 客户端收到后,确认了 服务端的接收能力发送能力 都是正常的。
  • 结论:此时客户端认为连接已经完全打通。

3. 第三次握手 (Client 回复 ACK)

核心目的:确认收到服务端的序列号 & 防止旧连接干扰

  • 确认收到: 告诉服务端:“我收到你的确认和序列号了,咱们可以开始了。”
  • 防止失效请求: 防止已失效的连接请求突然又传到了服务端,导致服务端错误地打开连接资源。
  • 能力验证(服务端视角):
  • 服务端收到后,确认了 自己的发送能力 是正常的(因为对方给回馈了)。
  • 服务端收到后,确认了 客户端的接收能力 是正常的。
  • 结论:此时服务端也认为连接完全打通。

四次挥手的意义

四次挥手的核心意义在于:TCP 连接是全双工(Full-Duplex)的

这意味着数据像是在两条独立的单行道上跑:一条是 客户端 -> 服务端,另一条是 服务端 -> 客户端每一条通道的关闭,都需要单独的确认

1. 第一次挥手 (Client 发送 FIN)

意义:客户端宣布“我没有新数据了”

  • 切断发送通道: 客户端告诉服务端:“我的数据已经全部发完了,我请求关闭我到你的这条数据通道。”
  • 保留接收能力: 此时客户端只是不再生成新数据,但如果服务端发来数据,客户端依然可以接收(这叫半关闭状态)。

2. 第二次挥手 (Server 回复 ACK)

意义:服务端确认收到,但申请“稍等”

  • 确认收到关闭请求: 服务端告诉客户端:“我知道你想断开了,但我这边可能还有数据没处理完(或者发送缓冲区的包还没发出去)。”
  • 防止数据丢失: 这一步非常关键。服务端不能立即关闭连接,否则缓冲区的剩余数据就丢了。服务端需要时间去处理这些“尾巴”。

3. 第三次挥手 (Server 发送 FIN)

意义:服务端宣布“我也处理完了”

  • 切断发送通道: 等服务端把剩余数据都发完后,它告诉客户端:“好了,我这边的数据也发完了,现在我也请求关闭我到你的这条通道。”
  • 正式结束服务: 此时服务端做好了完全断开的准备。

4. 第四次挥手 (Client 回复 ACK)

意义:客户端确认收到,连接彻底关闭

  • 确认完全结束: 客户端告诉服务端:“收到你的结束信号了,咱们的对话正式结束。”
  • 确保可靠关闭: 如果没有这一步,服务端不知道客户端是否收到了自己的 FIN。如果服务端没收到这个 ACK,它会以为自己的 FIN 丢了而不断重试。