当前位置: 首页 > article >正文

TCP的四次挥⼿为什么是四次?为什么不能是三 次

TCP 四次挥手(Four-way Handshake)用于终止一个已经建立的 TCP 连接。之所以是四次挥手,而不是三次,是因为 TCP 是全双工的(full-duplex),这意味着数据可以在两个方向上同时传输。因此,关闭连接需要双方分别确认关闭请求。

四次挥手的过程:

  1. FIN (Client -> Server):

    • 客户端想要关闭连接(假设客户端主动关闭)。
    • 客户端发送一个 FIN 报文段(FIN=1,seq=u)到服务器。
      • FIN=1 表示这是一个 FIN 报文段(请求关闭连接)。
      • seq=u 表示客户端的序列号。
    • 客户端进入 FIN_WAIT_1 状态。
  2. ACK (Server -> Client):

    • 服务器收到客户端的 FIN 报文段。
    • 服务器发送一个 ACK 报文段(ACK=1, seq=v, ack=u+1)到客户端。
      • ACK=1 表示这是一个 ACK 报文段。
      • seq=v 表示服务器的序列号。
      • ack=u+1 表示服务器期望接收的下一个序列号(即客户端的 FIN 报文段的序列号加 1)。
    • 服务器进入 CLOSE_WAIT 状态。
    • 客户端收到服务器的 ACK 报文段后,进入 FIN_WAIT_2 状态。
  3. FIN (Server -> Client):

    • 服务器准备好关闭连接(例如,服务器已经发送完所有数据)。
    • 服务器发送一个 FIN 报文段(FIN=1, seq=w, ack=u+1)到客户端。
      • FIN=1 表示这是一个 FIN 报文段。
      • seq=w 表示服务器的序列号 (注意, w可能等于v, 也可能不等于,取决于服务器是否在等待 ACK 期间发送了数据)。
      • ack=u+1,表示服务器期望接收的下一个序列号与上次 ACK 相同。
    • 服务器进入 LAST_ACK 状态。
  4. ACK (Client -> Server):

    • 客户端收到服务器的 FIN 报文段。
    • 客户端发送一个 ACK 报文段(ACK=1, seq=u+1, ack=w+1)到服务器。
      • ACK=1 表示这是一个 ACK 报文段。
      • seq=u+1 表示客户端的下一个序列号(即客户端上次发送的 FIN 报文段的序列号加 1)。
      • ack=w+1 表示客户端期望接收的下一个序列号(即服务器的 FIN 报文段的序列号加 1)。
    • 客户端进入 TIME_WAIT 状态(等待 2MSL 时间,以确保服务器收到 ACK,并防止延迟的报文段影响新的连接)。
    • 服务器收到客户端的 ACK 报文段后,进入 CLOSED 状态。

为什么不能是三次挥手?

不能是三次挥手的主要原因是 TCP 的半关闭(half-close)特性。

  • 半关闭: TCP 允许一方(例如客户端)关闭它的发送通道,但仍然可以接收数据。这意味着即使客户端发送了 FIN 报文段,它仍然可以接收来自服务器的数据,直到服务器也发送 FIN 报文段。

  • 三次挥手的问题: 如果只有三次挥手,服务器在收到客户端的 FIN 报文段后,立即发送 FIN+ACK 报文段,那么客户端就无法再接收服务器可能发送的剩余数据。

  • 四次挥手如何解决问题

    • 服务器收到客户端的FIN后,发送ACK,表示自己知道客户端要关闭连接了。
    • 但是服务器可能还有数据要发送,所以需要等待。
    • 当服务器数据发送完毕,再发送FIN给客户端。
    • 客户端回复ACK,连接关闭。

四次挥手的必要性:

  • 确保数据完整传输: 服务器在收到客户端的 FIN 报文段后,可以继续发送数据,直到数据发送完毕。
  • 允许半关闭: 客户端可以先关闭发送通道,但仍然可以接收数据。
  • 避免数据丢失: 四次挥手确保了双方都确认了对方要关闭连接,避免了数据丢失。

四次挥手的状态变化:

  • FIN_WAIT_1: 客户端发送 FIN 报文段后进入的状态。
  • FIN_WAIT_2: 客户端收到服务器的 ACK 报文段后进入的状态。
  • CLOSE_WAIT: 服务器收到客户端的 FIN 报文段后进入的状态。
  • LAST_ACK: 服务器发送 FIN 报文段后进入的状态。
  • TIME_WAIT: 客户端发送 ACK 报文段后进入的状态(等待 2MSL 时间)。
  • CLOSED: 连接完全关闭。

TIME_WAIT 状态的作用:

  • 确保服务器收到 ACK: 如果服务器没有收到客户端的 ACK 报文段,它会重传 FIN 报文段。TIME_WAIT 状态允许客户端重新发送 ACK 报文段。
  • 防止延迟的报文段影响新的连接: 2MSL (Maximum Segment Lifetime,报文段最大生存时间) 时间足够长,可以确保网络中所有延迟的报文段都消失,避免影响新的连接。

总结:

  • TCP 四次挥手是为了可靠地关闭全双工连接。
  • 不能是三次挥手,因为 TCP 支持半关闭,需要双方分别确认关闭请求。
  • 四次挥手确保了数据完整传输,允许半关闭,并避免了数据丢失。
  • TIME_WAIT 状态确保了服务器收到 ACK,并防止延迟的报文段影响新的连接。

四次挥手是 TCP 协议为了保证可靠性而设计的,虽然比三次挥手多了一次交互,但它确保了连接的正确关闭,避免了数据丢失和潜在的问题。


http://www.kler.cn/a/568931.html

相关文章:

  • 【计算机网络——概述】
  • 深搜专题7:最大质数
  • 【基于Raft的KV共识算法】-序:Raft概述
  • JavaEE基础之- 过滤器和监听器Filter and Listener
  • Deepseek 模型蒸馏
  • 每日OJ_牛客_NC316体育课测验(二)_拓扑排序_C++_Java
  • FPGA开发,使用Deepseek V3还是R1(3):系统级与RTL级
  • Ubuntu 下 nginx-1.24.0 源码分析 - ngx_init_cycle 函数 - 详解(8)
  • Ubuntu 20.04 安装 Node.js 20.x、npm、cnpm 和 pnpm 完整指南
  • LangPrompt提示词
  • 基于单片机的GPS定位系统设计
  • ETF期权的结算价如何结算?
  • 深度解析Ant Design Pro 6开发实践
  • 【MySQL】(2) 库的操作
  • 基于STM32的智能家居中控系统
  • 【定昌Linux系统】部署了java程序,设置开启启动
  • AndroidStudio下载旧版本方法
  • 16.5 LangChain LCEL 流式处理解密:构建实时交互式大模型应用的引擎
  • 【实战 ES】实战 Elasticsearch:快速上手与深度实践-2.1.2字段类型选择:keyword vs text、nested对象
  • JavaWeb登录认证