代码改变世界

TCP三次握手、四次挥手

  钟铧若岩  阅读(32)  评论(0编辑  收藏  举报
TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。三次握手和四次挥手是 TCP 协议建立和断开连接的重要过程,下面详细介绍。

TCP 三次握手

目的


三次握手的主要目的是在客户端和服务器之间建立可靠的连接,确保双方都具备发送和接收数据的能力,同时初始化序列号,为后续的数据传输做好准备。

过程


  1. 客户端向服务器发送 SYN 包
    • 客户端向服务器发送一个 TCP 数据包,其中 SYN(Synchronize Sequence Numbers,同步序列号)标志位被设置为 1,表示这是一个连接请求包。
    • 同时,客户端会随机选择一个初始序列号(Initial Sequence Number,ISN),假设为 x,并将其放入数据包的序列号字段中。
    • 客户端进入 SYN_SENT 状态,等待服务器的响应。
  2. 服务器收到 SYN 包并发送 SYN + ACK 包
    • 服务器接收到客户端的 SYN 包后,会为该连接分配必要的资源。
    • 服务器将 SYN 标志位和 ACK(Acknowledgment,确认)标志位都设置为 1,表示同意建立连接并对客户端的请求进行确认。
    • 服务器也会随机选择一个初始序列号,假设为 y,放入数据包的序列号字段中。同时,将确认号字段设置为 x + 1,表示已收到客户端的 SYN 包,期望接下来收到客户端序列号为 x + 1 的数据包。
    • 服务器进入 SYN_RCVD 状态。
  3. 客户端收到 SYN + ACK 包并发送 ACK 包
    • 客户端收到服务器的 SYN + ACK 包后,会检查确认号是否为 x + 1,如果是,则认为服务器已正确收到自己的 SYN 包。
    • 客户端将 ACK 标志位设置为 1,序列号字段设置为 x + 1,确认号字段设置为 y + 1,表示已收到服务器的 SYN 包,期望接下来收到服务器序列号为 y + 1 的数据包。
    • 客户端进入 ESTABLISHED 状态,此时客户端可以开始向服务器发送数据。
    • 服务器收到客户端的 ACK 包后,也进入 ESTABLISHED 状态,双方连接建立成功,可以进行数据传输。

示意图


 
客户端                               服务器
  |                                   |
  |  SYN=1, Seq=x                     |
  |  ------------------------------>  |
  |                                   |
  |  SYN=1, ACK=1, Seq=y, Ack=x+1     |
  |  <------------------------------  |
  |                                   |
  |  ACK=1, Seq=x+1, Ack=y+1          |
  |  ------------------------------>  |
  |                                   |
  |  连接建立,开始数据传输           |

TCP 四次挥手

目的


四次挥手的主要目的是在客户端和服务器之间安全、有序地关闭已建立的连接,确保双方都能正确处理未完成的数据传输和资源释放。

过程


  1. 客户端向服务器发送 FIN 包
    • 当客户端完成数据传输后,它会向服务器发送一个 TCP 数据包,其中 FIN(Finish,结束)标志位被设置为 1,表示请求关闭连接。
    • 假设客户端的序列号为 u,则将其放入数据包的序列号字段中。
    • 客户端进入 FIN_WAIT_1 状态,等待服务器的确认。
  2. 服务器收到 FIN 包并发送 ACK 包
    • 服务器接收到客户端的 FIN 包后,会立即发送一个 ACK 包进行确认。
    • 将 ACK 标志位设置为 1,序列号字段设置为 v(服务器当前的序列号),确认号字段设置为 u + 1,表示已收到客户端的 FIN 包,期望接下来收到客户端序列号为 u + 1 的数据包(虽然客户端已无数据要发送)。
    • 服务器进入 CLOSE_WAIT 状态,此时服务器可以继续向客户端发送未发送完的数据。
  3. 服务器向客户端发送 FIN 包
    • 当服务器完成数据传输后,它会向客户端发送一个 FIN 包,表示请求关闭连接。
    • 将 FIN 标志位设置为 1,序列号字段设置为 v(可能与上一个 ACK 包的序列号相同),确认号字段设置为 u + 1
    • 服务器进入 LAST_ACK 状态,等待客户端的确认。
  4. 客户端收到 FIN 包并发送 ACK 包
    • 客户端收到服务器的 FIN 包后,会发送一个 ACK 包进行确认。
    • 将 ACK 标志位设置为 1,序列号字段设置为 u + 1,确认号字段设置为 v + 1,表示已收到服务器的 FIN 包,期望接下来收到服务器序列号为 v + 1 的数据包(实际上服务器已无数据要发送)。
    • 客户端进入 TIME_WAIT 状态,等待一段时间(通常为 2 倍的最大段生存期,即 2MSL),以确保服务器能收到自己的 ACK 包。如果服务器未收到 ACK 包,会重新发送 FIN 包,客户端可以再次发送 ACK 包进行确认。
    • 服务器收到客户端的 ACK 包后,进入 CLOSED 状态,连接关闭。客户端在 TIME_WAIT 状态等待一段时间后,也进入 CLOSED 状态,连接彻底关闭。

示意图


 
 
客户端                               服务器
  |                                   |
  |  FIN=1, Seq=u                     |
  |  ------------------------------>  |
  |                                   |
  |  ACK=1, Seq=v, Ack=u+1            |
  |  <------------------------------  |
  |                                   |
  |  FIN=1, ACK=1, Seq=v, Ack=u+1     |
  |  <------------------------------  |
  |                                   |
  |  ACK=1, Seq=u+1, Ack=v+1          |
  |  ------------------------------>  |
  |                                   |
  |  连接关闭                         |

总结


TCP 三次握手和四次挥手是确保 TCP 连接可靠建立和安全关闭的重要机制,它们通过一系列的数据包交换和状态转换,保证了通信双方的同步和数据的完整性。
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示