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

TCP 连接:三次握手与四次挥手

TCP 协议,全称为“传输控制协议”。

1. TCP 协议段格式

给出几个定义 :

  • 16位源端口号 :用于标识发送端的应用程序。

  • 16位目的端口号 :用于标识接收端的目标应用程序。

  • 32位序号 :用于标识发送的每一个字节流中的第一个字节位置;确保接收端能够按照正确的顺序重组数据,即使数据包在传输中乱序到达。

  • 32位确认序号 :用于告知发送端,“我已经成功接收 这个序号之前的所有数据 ,现在请从这个序号开始给我发新的数据” 。

  • 4位首部长度 :指示 TCP 头部的长度,以 4字节 为单位;首部长度 的范围是 5~15,标识 TCP 头部的长度为 20~60 字节。

  • 标志位 :用于控制 TCP 连接的状态。SYNACKFINRSTPSHURG

2. 三次握手
2.1 传统的三次握手过程

在这里插入图片描述

三次握手过程,确保了两个主机都可以互相发送和接收数据。

服务端状态变化:

  • CLOSED —> LISTEN :服务端调用 listen() 后进入 LISTEN 状态,等待客户端连接。
  • LISTEN —> SYN_RCVD :监听到连接请求(即收到 SYN 包),将该连接放入内核等待队列,并向客户端发送 SYN-ACK 包。
  • SYN_RCVD —> ESTABLISHED :服务端收到客户端的 ACK 包后进入 ESTABLISHED 状态,可以读写数据。

客户端状态变化:

  • CLOSED —> SYN_SENT :客户端调用 connect(),发送 SYN 报文。
  • SYN_SENT —> ESTABLISHED :调用 connect() 成功,收到来自服务器的 SYN-ACK 包后,进入 ESTABLISHED 状态。
2.2 三次握手过程触发 RST

在 TCP 三次握手过程中,被请求建立连接的那一端尚未完成握手(未收到最终的 ACK 包),就意外收到了数据包,则触发 RST(连接重置)

RST 包的作用:

  • 立即中断连接,告知对方当前连接不可用。
  • 释放相关资源,避免内存泄露。

客户端收到 RST 包后,需要重新进行三次握手,建立连接。

3. 四次挥手
3.1 四次挥手过程

客户端状态变化:

  • ESTABLISTED —> FIN_WAIT_1 :客户端调用 close() ,向服务端发送 FIN 报文,并进入 FIN_WAIT_1 状态。

​ 通知服务器,客户端没有数据要发送了,但仍然可以接收数据

  • FIN_WAIT_1 —> FIN_WAIT_2 :客户端收到来自服务器的 ACK 报文,进入 FIN_WAIT_2 状态。

  • FIN_WAIT_2 —> TIME_WAIT :客户端收到来自服务器的 FIN 报文,进入 TIME_WAIT 状态,发出最后一个 ACK 包。

服务器状态变化:

  • ESTABLISHED —> CLOSE_WAIT :客户端主动关闭连接,服务器收到 FIN 报文后回应 ACK ,并进入 CLOSE_WAIT 状态。

  • CLOSE_WAIT —> LAST_ACK :进入 CLOSE_WAIT 状态后,服务器准备关闭连接,处理所有剩余数据;

    服务器真正调用 close() 关闭连接,向客户端发送 FIN 报文并进入 LAST_ACK 状态,等待最后一个 ACK(确认)。

  • LAST_ACK —> CLOSED :服务器收到了客户端对 FIN 的 ACK,关闭连接。

3.2 CLOSE_WAIT 状态

创建一个简易的 TCP 服务器和 TCP 客户端,并建立连接。

直接关闭客户端。

此时服务端进入 CLOSE_WAIT 状态,四次挥手没有完成。

如果服务器上大量出现 CLOSE_WAIT 状态,意味着服务器没有正确地关闭 socket ,导致四次挥手没有正常完成。

需要加上对应的 close ,解决此问题。

3.3 TIME_WAIT 状态

3.2 相同,创建一个简易的 TCP 服务器和客户端,并建立连接。

直接关闭服务器,再重新运行。

服务器进入 TIME_WAIT 状态。

TCP 协议规定,主动关闭连接的一方要处于 TIME_WAIT 状态,等待两个 MSL(maximum segment lifetime)的时间后,才能回到 CLOSED 状态。

  • MSL 是 TCP 报文的最大生存时间。

  • 保证在传输方向上的尚未被接收、或迟到的报文段都已消失;否则服务器立即重启,会收到来自上个进程的迟到数据。

  • 保证最后一个 ACK 报文可靠到达;如果最后一个 ACK 丢失,服务器会重发一个 FIN 数据报(客户端进程虽然不在,但 TCP 连接还在,可以重发 ACK)。


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

相关文章:

  • Chapter4.2:Normalizing activations with layer normalization
  • C++编程库与框架实战——ZeroMQ消息队列
  • Redission红锁
  • PostgreSQL对称between比较运算
  • SpringCloudAlibaba实战入门之路由网关Gateway过滤器(十三)
  • 更改element-plus的table样式
  • gazebo_world 基本围墙。
  • gitlab runner 实现 微信小程序自动化部署
  • Flutter 插件开发入门
  • frameworks 之 WMS添加窗口流程
  • 嵌入式开发 的循环实现
  • 牛客周赛 Round 66 E题 小苯的蓄水池(hard)
  • 【电路复习--选择题】
  • 【汇编】关于函数调用过程的若干问题
  • 选择排序cYuyan
  • 破解无人机能源瓶颈:优化调度与智能布局的实践
  • mongdb的简介和使用
  • 面向机器学习的Java库与平台
  • cellphoneDB进行CCI以及可视化
  • TCP网络编程(二)—— 服务器端的编写
  • Upload-labs 靶场(学习)
  • 【Linux】Socket编程-UDP构建自己的C++服务器
  • 3.微服务灰度发布落地实践(组件灰度增强)
  • AI 自动化编程的现状与局限
  • delete,drop,truncate的区别
  • ChatGPT与Postman协作完成接口测试(四)