深入理解TCP四次挥手:状态转换全流程实战解析
一、引言在上一篇文章中,我们详细讲解了TCP三次握手的过程。本文将聚焦于TCP连接断开的完整流程——四次挥手,通过详细的代码示例和实时状态监控,帮助你彻底理解连接关闭过程中的每一个状态转换细节。二、四次挥手核心概念2.1 为什么是四次挥手?TCP是全双工通信,连接的每个方向必须单独关闭:客户端 ←─────数据流1─────→ 服务器 ←─────数据流2─────→ 关闭数据流1 ≠ 关闭数据流2 因此需要四次挥手分别关闭两个方向2.2 四次挥手完整流程图主动关闭方(客户端) 被动关闭方(服务器) ESTABLISHED ESTABLISHED | | | close() | | 发送FIN | ↓ | FIN_WAIT_1 --------[FIN, seq=u]-------→ | | ↓ | CLOSE_WAIT | ←-------[ACK, ack=u+1]---------| ↓ | FIN_WAIT_2 | (可继续发送数据) | | | | close() | ↓ | ←----[FIN, seq=w]----------LAST_ACK ↓ | TIME_WAIT ------[ACK, ack=w+1]--------→ | | ↓ | (等待2MSL) CLOSED ↓ CLOSED三、客户端主动断开连接实现3.1 完整客户端代码#includestdio.h#includestdlib.h#includestring.h#includeunistd.h#includearpa/inet.h#includesys/socket.h#includenetinet/tcp.h#includetime.h#defineSERVER_IP"127.0.0.1"#defineSERVER_PORT8888// 获取TCP状态名称constchar*get_tcp_state_name(intstate){switch(state){caseTCP_ESTABLISHED:return"ESTABLISHED";caseTCP_SYN_SENT:return"SYN_SENT";caseTCP_SYN_RECV:return"SYN_RECV";caseTCP_FIN_WAIT1:return"FIN_WAIT1";caseTCP_FIN_WAIT2:return"FIN_WAIT2";caseTCP_TIME_WAIT:return"TIME_WAIT";caseTCP_CLOSE:return"CLOSE";caseTCP_CLOSE_WAIT:return"CLOSE_WAIT";caseTCP_LAST_ACK:return"LAST_ACK";caseTCP_LISTEN:return"LISTEN";caseTCP_CLOSING:return"CLOSING";default:return"UNKNOWN";}}// 获取当前TCP状态intget_tcp_state(intsockfd){structtcp_infoinfo;socklen_tinfo_len=sizeof(info);if(getsockopt(sockfd,IPPROTO_TCP,TCP_INFO,info,info_len)==0){returninfo.tcpi_state;}return-1;}// 打印带时间戳的状态信息voidprint_state(constchar*stage,intsockfd){time_tnow=time(NULL);structtm*tm_info=localtime(now);chartime_str[20];strftime(time_str,sizeof(time_str),"%H:%M:%S",tm_info);intstate=get_tcp_state(sockfd);printf("[%s] %s - 当前状态: %s\n",time_str,stage,get_tcp_state_name(state));}intmain(){intsockfd;structsockaddr_inservaddr;charbuffer[1024];printf("═══════════════════════════════════════\n");printf(" TCP四次挥手实战 - 客户端主动断开\n");printf("═══════════════════════════════════════\n\n");// 步骤1: 创建socket并连接sockfd=socket(AF_INET,SOCK_STREAM,0);if(sockfd0){perror("socket error");exit(1);}memset(servaddr,0,sizeof(servaddr));servaddr.sin_family=AF_INET;servaddr.sin_port=htons(SERVER_PORT);inet_pton(AF_INET,SERVER_IP,servaddr.sin_addr);printf("🚀 连接服务器 %s:%d...\n",SERVER_IP,SERVER_PORT);if(connect(sockfd,(structsockaddr*)servaddr,sizeof(servaddr))0){perror("connect error");exit(1);}print_state("✓ 连接建立",sockfd);printf("\n");// 步骤2: 发送测试数据printf("📡 数据传输阶段...\n");for(inti=1;i=3;i++){snprintf(buffer,sizeof(buffer),"测试消息 #%d\n",i);write(sockfd,buffer,strlen(buffer));printf(" 发送: %s",buffer);intn=read(sockfd,buffer,sizeof(buffer)-1);if(n0){buffer[n]='\0';printf(" 收到: %s",buffer);}print_state(" 数据传输中",sockfd);sleep(1);}printf("\n");printf("═══════════════════════════════════════\n");printf("🔚 开始四次挥手过程...\n");printf("═══════════════════════════════════════\n\n");// 步骤3: 第一次挥手 - 客户端发送FINprintf("【第1次挥手】客户端主动关闭\n");printf(" → 操作: 调用 close() 函数\n");printf(" → 动作: 发送 FIN 标志位\n");print_state(" → 状态变化",sockfd);printf(" → 预期状态: ESTABLISHED → FIN_WAIT1\n\n");sleep(1);// 关闭socket(触发FIN发送)shutdown(sockfd,SHUT_WR);// 先关闭写端,观察状态sleep(1);print_state(" 实际状态",sockfd);// 步骤4: 第二次挥手 - 接收服务器ACKprintf("\n【第2次挥手】收到服务器ACK\n");printf(" ← 服务器动作: 回复 ACK 确认\n");printf(" ← 服务器状态: ESTABLISHED → CLOSE_WAIT\n");printf(" → 客户端状态: FIN_WAIT1 → FIN_WAIT2\n");sleep(2);print_state(" 当前状态",sockfd);// 步骤5: 第三次挥手 - 接收服务器FINprintf("\n【第3次挥手】收到服务器FIN\n");printf(" ← 服务器动作: 发送 FIN 标志位\n");printf(" ← 服务器状态: CLOSE_WAIT → LAST_ACK\n");printf(" → 客户端状态: FIN_WAIT2 → TIME_WAIT\n");// 尝试读取,检测服务器是否发送FINintn=read(sockfd,buffer,sizeof(buffer));if(n==0){printf(" ✓ 检测到服务器关闭连接 (收到FIN)\n");}sleep(1);print_state(" 当前状态",sockfd);// 步骤6: 第四次挥手 - 发送最后的ACKprintf("\n【第4次挥手】客户端发送最后的ACK\n");printf(" → 动作: 自动回复 ACK\n");printf(" → 客户端状态: 保持 TIME_WAIT\n");printf(" ← 服务器状态: LAST_ACK → CLOSED\n\n");// 完全关闭连接close(sockfd);printf("⏳ 进入 TIME_WAIT 状态\n");printf(" → 持续时间: 2MSL (约60秒)\n");printf(" → 目的1: 确保服务器收到最后的ACK\n");printf(" → 目的2: 防止旧连接数据包干扰新连接\n\n");printf("✓ 四次挥手完成\n");printf(

相关新闻

惊爆!Anthropic怒斥中国AI“偷师”,1600万次对话背后的罗生门:到底谁在蒸馏谁?

惊爆!Anthropic怒斥中国AI“偷师”,1600万次对话背后的罗生门:到底谁在蒸馏谁?

“他们怎么敢偷Anthropic从人类程序员那里偷来的东西?” —— 埃隆马斯克 如果人工智能界也有“武林大会”,那么2026年2月23日这天,绝对称得上是“光明顶决战”的前夜。 美国AI巨头Anthropic突然在官网和社交平台X上甩出一篇“檄文”,指控中国的三家AI实验室——DeepSeek(…

2026/7/3 20:20:10 阅读更多 →
本地化语音识别:突破性能瓶颈的终极实践指南

本地化语音识别:突破性能瓶颈的终极实践指南

本地化语音识别:突破性能瓶颈的终极实践指南 【免费下载链接】whisper.cpp OpenAI 的 Whisper 模型在 C/C 中的移植版本。 项目地址: https://gitcode.com/GitHub_Trending/wh/whisper.cpp 在数字化办公与智能交互日益普及的今天,离线语音转文字技…

2026/7/3 3:30:15 阅读更多 →
重新定义二维绘图:LitCAD开源平台如何让设计效率提升300%

重新定义二维绘图:LitCAD开源平台如何让设计效率提升300%

重新定义二维绘图:LitCAD开源平台如何让设计效率提升300% 【免费下载链接】LitCAD A very simple CAD developed by C#. 项目地址: https://gitcode.com/gh_mirrors/li/LitCAD 副标题:面向设计师与工程师的轻量级CAD解决方案,告别复杂…

2026/5/17 7:55:37 阅读更多 →

最新新闻

AI Agent如何重塑数据库运维:从诊断到执行的智能闭环

AI Agent如何重塑数据库运维:从诊断到执行的智能闭环

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Claude 随心用,限时 5 折。 👉 点击领海量免费额度 凌晨三点,告警群突然炸响。数据库 CPU 瞬间飙到 100%,业务接口大面积超时。值班 DBA 从睡梦中惊醒&#xff…

2026/7/4 1:13:12 阅读更多 →
量化投资策略与风险管理实战指南

量化投资策略与风险管理实战指南

1. 投资纪律与理性决策的价值重塑在经历了2023-2024年的市场剧烈波动后,我深刻体会到投资本质上是一场与人性弱点的持久战。这个复盘记录不仅是对过去两年操作的系统梳理,更是对投资方法论的一次全面升级。当市场情绪极端化时,那些看似简单的…

2026/7/4 1:13:12 阅读更多 →
Java开发中正确使用异常而不是滥用异常

Java开发中正确使用异常而不是滥用异常

你是否遇到过这样的代码:整个方法被一个巨大的try-catch包裹,catch块里直接打印一行日志然后返回null,调用方还要小心翼翼地判断是否为null?又或者,检查性异常被疯狂地往上抛,直到最上层被盲目地捕获并吞掉…

2026/7/4 1:13:12 阅读更多 →
AI Agent如何重塑数据库运维:从诊断、安全到可进化Skill生态

AI Agent如何重塑数据库运维:从诊断、安全到可进化Skill生态

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Claude 随心用,限时 5 折。 👉 点击领海量免费额度 凌晨三点,告警群突然炸响。数据库 CPU 瞬间飙到 100%,业务接口大面积超时。值班的 DBA 从睡梦中惊醒&#x…

2026/7/4 1:13:12 阅读更多 →
OpenMontage:用AI编程助手自动化视频制作,降低技术内容创作门槛

OpenMontage:用AI编程助手自动化视频制作,降低技术内容创作门槛

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Claude 随心用,限时 5 折。 👉 点击领海量免费额度 这次我们来看一个在 GitHub 上获得超过 12K 星的开源项目:OpenMontage。它不是一个独立的 AI 视频生成器,而…

2026/7/4 1:11:11 阅读更多 →
AMD Ryzen处理器深度调试完全指南:5分钟掌握SMU Debug Tool核心功能

AMD Ryzen处理器深度调试完全指南:5分钟掌握SMU Debug Tool核心功能

AMD Ryzen处理器深度调试完全指南:5分钟掌握SMU Debug Tool核心功能 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址…

2026/7/4 1:07:10 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻