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

TCP 四次挥手

引言:优雅的告别

在网络通信中,建立连接需要三次握手,而终止连接则需要四次挥手。这种设计体现了 TCP 协议的可靠性和完整性原则。本文将用通俗易懂的方式,深入解析四次挥手的原理、状态转换和实际应用,帮助您掌握这一网络通信的核心机制。

一、四次挥手:为何需要四步?

想象两个朋友结束通话的场景:

  1. A 说:“我说完了,要挂电话了”(第一次挥手)
  2. B 回答:“好的,我听到了”(第二次挥手)
  3. B 补充:“我也说完了,要挂了”(第三次挥手)
  4. A 确认:“好的,再见”(第四次挥手)

TCP 四次挥手也是类似的双向确认过程:

主动关闭方 被动关闭方 发送完所有数据 FIN (我要关闭发送通道) 收到关闭请求 ACK (收到你的请求) 处理剩余数据 FIN (我也要关闭发送通道) 收到关闭请求 ACK (收到你的请求) 立即关闭连接 等待2MSL后关闭 主动关闭方 被动关闭方

二、状态转换图解(精准版)

主动关闭方
被动关闭方
close()/shutdown()
收到ACK
收到FIN
2MSL超时
收到FIN
close()/shutdown()
收到ACK
ESTABLISHED
FIN_WAIT_1
FIN_WAIT_2
TIME_WAIT
CLOSED
CLOSE_WAIT
LAST_ACK

关键状态解析:

  1. FIN_WAIT_1:主动方已发送FIN,等待确认
  2. FIN_WAIT_2:收到第一次ACK,等待对方FIN
  3. CLOSE_WAIT:被动方收到FIN,准备关闭
  4. LAST_ACK:被动方发送FIN,等待最后确认
  5. TIME_WAIT:主动方确保对方收到ACK(等待2MSL)

MSL(Maximum Segment Lifetime):报文最大生存时间,通常30-120秒

三、核心函数与代码示例

主动关闭方(客户端):

// 发送完数据后关闭连接
close(sockfd); // 或者优雅关闭(推荐)
shutdown(sockfd, SHUT_WR); // 先关闭写通道
// 继续读取剩余数据...
close(sockfd);             // 完全关闭

被动关闭方(服务端):

while ((bytes = read(sockfd, buffer, BUFFER_SIZE)) > 0) {// 处理数据...
}if (bytes == 0) { // 收到FIN(EOF)close(sockfd); // 关闭连接触发第三次挥手
}

四、为什么需要TIME_WAIT状态?

TIME_WAIT 是面试必问知识点!它有两个关键作用:

  1. 确保最后一个ACK到达
    如果ACK丢失,被动方会重发FIN,TIME_WAIT状态能重新发送ACK

  2. 防止旧连接数据混淆
    等待2MSL确保网络中属于该连接的报文全部消失,避免影响新连接

查看TIME_WAIT连接:

netstat -n | grep TIME_WAIT
ss -tan | grep TIME-WAIT

五、常见问题与解决方案

问题1:服务器出现大量CLOSE_WAIT

  • 原因:应用未调用close()
  • 解决:检查代码资源释放逻辑,确保每个socket都被关闭

问题2:TIME_WAIT过多导致端口耗尽

  • 优化方案
    # 启用TIME_WAIT重用(Linux)
    sysctl -w net.ipv4.tcp_tw_reuse=1# 减少FIN超时时间
    sysctl -w net.ipv4.tcp_fin_timeout=30
    

问题3:连接卡在FIN_WAIT_2

  • 原因:被动方未发送FIN
  • 解决:检查被动方应用是否正常关闭连接

六、实际抓包分析(Wireshark示例)

No.  Time     Source       Destination  Protocol Info
1    0.000   192.168.1.1  192.168.1.2  TCP      [FIN], Seq=100
2    0.001   192.168.1.2  192.168.1.1  TCP      [ACK], Ack=101
3    1.002   192.168.1.2  192.168.1.1  TCP      [FIN], Seq=300
4    1.002   192.168.1.1  192.168.1.2  TCP      [ACK], Ack=301

关键点:

  • FIN和ACK标志位的变化
  • 序列号(Seq)和确认号(Ack)的连续性
  • 时间间隔(可能包含数据处理时间)

总结:四次挥手的核心价值

  1. 可靠性:通过四次交互确保双方都完成数据发送
  2. 有序性:状态机管理确保关闭过程有序进行
  3. 安全性:TIME_WAIT防止报文混淆和丢失
  4. 灵活性:支持半关闭(shutdown)等高级用法

最佳实践

  • 服务端使用连接池减少握手/挥手开销
  • 客户端使用优雅关闭(shutdown)避免数据丢失
  • 监控关键状态(CLOSE_WAIT/TIME_WAIT)预防资源泄漏

理解四次挥手不仅有助于解决网络问题,更能帮助开发者设计高性能、高可靠的网络应用。当你下次看到TIME_WAIT时,请记得这是TCP为保障可靠性所做的最后努力。

相关文章:

TCP 四次挥手

引言:优雅的告别 在网络通信中,建立连接需要三次握手,而终止连接则需要四次挥手。这种设计体现了 TCP 协议的可靠性和完整性原则。本文将用通俗易懂的方式,深入解析四次挥手的原理、状态转换和实际应用,帮助您掌握这一…...

MSTNet:用于糖尿病视网膜病变分类的多尺度空间感知 Transformer 与多实例学习方法|文献速递-深度学习医疗AI最新文献

Title 题目 MSTNet: Multi-scale spatial-aware transformer with multi-instance learning for diabetic retinopathy classification MSTNet:用于糖尿病视网膜病变分类的多尺度空间感知 Transformer 与多实例学习方法 01 文献速递介绍 糖尿病视网膜病变&#…...

docker运行程序Killed异常排查

问题描述 我最近开发了一个C 多线程程序,测试没有问题,封装docker测试也没有问题,然后提交给客户了,然后在他那边测试有问题,不定时、不定位置异常中断,以前一直认为只要封装了docker就万事大吉&#xff0…...

【数学 逆序对 构造】P12386 [蓝桥杯 2023 省 Python B] 混乱的数组|普及+

本文涉及知识点 数学 构造 P12386 [蓝桥杯 2023 省 Python B] 混乱的数组 题目描述 给定一个正整数 x x x&#xff0c;请找出一个尽可能短的仅含正整数的数组 A A A 使得 A A A 中恰好有 x x x 对 i , j i, j i,j 满足 i < j i < j i<j 且 A i > A j A_…...

Excel 批量下载PDF、批量下载考勤图片——仙盟创梦IDE

在办公场景中&#xff0c;借助应用软件实现 Excel 批量处理考勤图片、电子文档与 PDF&#xff0c;具有诸多显著优势。 从考勤图片处理来看&#xff0c;通过 Excel 批量操作&#xff0c;能快速提取图片中的考勤信息&#xff0c;如员工打卡时间、面部识别数据等&#xff0c;节省…...

PCIe-Error Detection(一)

下表为PCIe协议中给出的错误&#xff1a; 一、可纠正错误&#xff08;Correctable Errors&#xff0c;8种&#xff09;​​ ​​检错机制​​ ​​错误名称​​​​检测层级​​​​触发条件​​​​Receiver Error​​Physical接收端均衡器&#xff08;EQ&#xff09;监测到…...

向量空间的练习题目

1.考虑 中的向量x1 和x2 求每一向量的长度 令x3x1x2,求x3的长度&#xff0c;它的长度与x1和x2的和有什么关系&#xff1f; 2.重复练习1&#xff0c;取向量 3.令C为复数集合&#xff0c;定义C上的加法为 (abi)(cdi)(ac)(bd)i 并定义标量乘法为对所有实数a (abi) a bi 证明&…...

Leetcode 2123. 使矩阵中的 1 互不相邻的最小操作数

1.题目基本信息 1.1.题目描述 给你一个 下标从 0 开始 的矩阵 grid。每次操作&#xff0c;你可以把 grid 中的 一个 1 变成 0 。 如果一个矩阵中&#xff0c;没有 1 与其它的 1 四连通&#xff08;也就是说所有 1 在上下左右四个方向上不能与其他 1 相邻&#xff09;&#x…...

MySQL高可用集群

https://dev.mysql.com/doc/mysql-shell/8.4/en/mysql-innodb-cluster.html 1 什么是MySQL高可用集群 MySQL高可用集群&#xff1a;MySQL InnoDB ClusterInnoDB Cluster是MySQL官方实现高可用读写分离的架构方案&#xff0c;包含以下组件 MySQL Group Replication&#xff1a;简…...

day14 leetcode-hot100-27(链表6)

21. 合并两个有序链表 - 力扣&#xff08;LeetCode&#xff09; 1. 暴力法 思路 创建一个空节点&#xff0c;用来组装这两个链表&#xff0c;谁小谁就是下一个节点。 知识 创建空节点&#xff1a;ListNode n1 new ListNode(-1); 具体代码 /*** Definition for singly-l…...

YOLOv5 :训练自己的数据集

- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营](https://mp.weixin.qq.com/s/rnFa-IeY93EpjVu0yzzjkw) 中的学习记录博客** - **&#x1f356; 原作者&#xff1a;[K同学啊](https://mtyjkh.blog.csdn.net/)** 我们接着上一篇文章配置完YOLOv5需要的环境后&#…...

flutter项目迁移空安全

重中之重 备份好项目文件&#xff0c;甚至连已经加载好的flutter库也可以备份。环境包升级 2.1 不要直接换成flutter:3.0以上的版本&#xff0c;这样做既有基本的库兼容问题&#xff0c;又有空安全下的语法问题(整个项目中需要增加 late、?、!的语法错误&#xff0c;一片报错的…...

vue element日期范围选择器只能选择指定天数内的

<el-date-pickerv-model"dateRange"type"daterange"range-separator"至"start-placeholder"开始日期"end-placeholder"结束日期"format"yyyy-MM-dd"value-format"yyyy-MM-dd"clearable:picker-optio…...

从 AMQP 到 RabbitMQ:核心组件设计与工作原理(二)

五、RabbitMQ 工作原理全揭秘 在深入了解了 RabbitMQ 的核心组件之后&#xff0c;接下来让我们深入探究 RabbitMQ 的工作原理&#xff0c;揭开其在消息生产、投递、消费以及可靠性保障等方面的神秘面纱。 5.1 消息生产与投递流程 建立连接与信道&#xff1a;生产者首先通过 …...

MySql(十二)

目录 MySql约束 1.添加主键约束 语法格式 1&#xff09;创建一个带主键的表 查看表结构 2&#xff09;创建表的时候指定主键名称 查看表结构 3&#xff09;创建一个表然后&#xff0c;然后再使用alter为列添加主键 查看表结构 4&#xff09;为表添加数据 1---正常数据 2---主键…...

51c视觉~3D~合集3

我自己的原文哦~ https://blog.51cto.com/whaosoft/13954440 #SceneTracker 在4D时空中追踪万物&#xff01;国防科大提出首个长时场景流估计方法 本篇分享 TPAMI 2025 论文​​SceneTracker: Long-term Scene Flow Estimation Network​​&#xff0c;国防科大提出首…...

windows11安装编译QtMvvm

windows11安装编译QtMvvm 1 从github下载代码2 官方的Download/Installtion3 自行构建编译QtMvvm遇到的问题3.1 `qmake`问题执行命令报错原因分析qmake报错:找不到编译器 cl解决方案3.2 `make qmake_all`问题执行命令报错原因分析make命令未识别解决方案3.3 缺少`perl`问题执行…...

【2025年电工杯数学建模竞赛A题】光伏电站发电功率日前预测问题+完整思路+paper+源码

本人7年数学建模竞赛经验&#xff0c;历史获奖率百分之百。团队成员都是拿过全国一等奖的硕博&#xff0c;有需要数模竞赛帮助的可以私信我 本题主要涉及数据预测&#xff0c;数据分析&#xff0c;机器学习&#xff0c;时间序列等知识 1.问题背景与问题描述 2.解题思路分析 …...

OpenCv高阶(十九)——dlib关键点定位

文章目录 一、什么是人脸关键点定位&#xff1f;二、关键点模型的下载及关键信息的理解三、dlib关键点定位的简单实现&#xff08;1&#xff09;导入必要的库&#xff08;2&#xff09;从指定路径读取图像文件&#xff08;3&#xff09;创建dlib的正面人脸检测器对象&#xff0…...

BUUCTF之[ACTF2020 新生赛]BackupFile

打开环境就一句话 找出源文件! 结合题目名字&#xff1a;BackupFile 先用dirsearct扫描网站文件 发现一个index.php.bak ,拼接url下载 打开发现php代码 <?php include_once "flag.php";if(isset($_GET[key])) {$key $_GET[key];if(!is_numeric($key)) {exit…...

头歌之动手学人工智能-Pytorch 之autograd

目录 第1关&#xff1a;Variable 任务描述 编程要求 测试说明 没有伟大的愿望&#xff0c;就没有伟大的天才。——巴尔扎克开始你的任务吧&#xff0c;祝你成功&#xff01; 第2关&#xff1a;Variable 属性 任务描述 编程要求 测试说明 真正的科学家应当是个幻想家&a…...

OIer常用的软件

前言 现在许多软件的官网多不好找&#xff0c;所以我今天就将常用的一些软件官网地址翻了出来&#xff0c;并简单介绍了他的用法。 正文 1.DEV-C DEV-C 用途&#xff1a;c编译软件&#xff0c;是OIer的生涯之路的必备软件 2.Katex KATex 用途&#xff1a;展现公式的软件&…...

Centos7.x内网环境Jenkins前端打包环境配置

Centos7.x内网环境Jenkins前端打包环境配置 参考地址&#xff1a; https://www.cnblogs.com/guangdelw/p/18763336 https://2048.csdn.net/682c1be8606a8318e857d687.html 前言&#xff1a;环境描述和目标 最近公司新接了一个项目&#xff0c;要求是&#xff1a;需要再桌面…...

Kafka集成Flume/Spark/Flink(大数据)/SpringBoot

Kafka集成Flume Flume生产者 ③、安装Flume&#xff0c;上传apache-flume的压缩包.tar.gz到Linux系统的software&#xff0c;并解压到/opt/module目录下&#xff0c;并修改其名称为flume Flume消费者 Kafka集成Spark 生产者 object SparkKafkaProducer{def main(args:Array[S…...

Scratch节日 | 拯救屈原 | 端午节

端午节快乐&#xff01; 这款特别为端午节打造的Scratch游戏 《拯救屈原》&#xff0c;将带你走进古代中国&#xff0c;感受历史与文化的魅力&#xff01; &#x1f3ee; 游戏介绍 扮演勇敢的探险者&#xff0c;穿越时空回到古代&#xff0c;解锁谜题&#xff0c;完成任务&…...

rabbitmq Direct交换机简介

在实际开发中&#xff0c;需求可能变得复杂&#xff0c;如消息的收发和处理。以支付系统为例&#xff0c;成功支付后需要改变订单状态并通知用户&#xff0c;而失败则不需要。为处理这种情况&#xff0c;提出了使用Direct交换机&#xff0c;它可以根据规则将消息路由到指定队列…...

Git实战--基于已有分支克隆进行项目开发的完整流程

Git克隆项目开发流程 ✅ 一、完整流程概述✅ 二、详细操作步骤Step 1&#xff1a;克隆仓库&#xff08;如果尚未克隆&#xff09;Step 2&#xff1a;获取远程分支信息并切换到 feature/ 获取所有远程分支Step 3&#xff1a;创建并切换到你的新分支Step 4&#xff1a;开始开发新…...

MapReduce(期末速成版)

起初在B站看3分钟的速成视频&#xff0c;感觉很多细节没听懂。 具体例子解析(文件内容去重) 对于两个输入文件&#xff0c;即文件A 和文件B&#xff0c;请编写MapReduce 程序&#xff0c;对两个文件进行合并&#xff0c;并剔除 其中重复的内容&#xff0c;得到一个新的输出文件…...

鸿蒙OSUniApp 移动端直播流播放实战:打造符合鸿蒙设计风格的播放器#三方框架 #Uniapp

UniApp 移动端直播流播放实战&#xff1a;打造符合鸿蒙设计风格的播放器 在移动互联网时代&#xff0c;直播已经成为一种主流的内容形式。本文将详细介绍如何使用 UniApp 框架开发一个优雅的直播流播放器&#xff0c;并融入鸿蒙系统的设计理念&#xff0c;实现一个既美观又实用…...

C3、C2f、C3K2、C2PSA的具体结构

YOLOV5 C3 Bottleneck C2f...