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

Java学习第八十七部分——四次挥手

目录

一、前言提要

二、详细过程——总体上分析

三、详细过程——结合Java代码分析

四、关键问题解析

五、总结归纳概述


一、前言提要

       TCP 使用四次挥手(Four-way Handshake)来安全关闭连接,确保双方数据传输完整。

二、详细过程——总体上分析

(一)流程图

(二)步骤详解

第一次挥手(FIN)

主动方(如客户端):发送 FIN=1seq=u),进入 FIN-WAIT-1 状态,表示不再发送数据。

第二次挥手(ACK)

被动方(如服务器):返回 ACK=1ack=u+1),进入 CLOSE-WAIT 状态,但仍可发送剩余数据。

主动方: 收到后进入 FIN-WAIT-2 状态。

第三次挥手(FIN)

被动方 :发送 FIN=1seq=v),进入 LAST-ACK 状态,表示不再发送数据。

第四次挥手(ACK)

主动方 :返回 ACK=1ack=v+1),进入 TIME-WAIT 状态(等待 2MSL 时间)

被动方 :立即关闭。

步骤发送方TCP标志Java对应操作状态变化
第一次挥手客户端FINsocket.close()FIN-WAIT-1
第二次挥手服务器ACKin.read()返回-1CLOSE-WAIT
第三次挥手服务器FINsocket.close()LAST-ACK
第四次挥手客户端ACK自动发送ACKTIME-WAIT → CLOSED
缩写全称含义
FINFinish终止连接标志位(FIN=1表示请求关闭连接)。
ACKAcknowledgment确认标志位,ack值为对端FIN的序列号+1(确认关闭请求)。

(三)白话解释

1. 客户端:我不需要请求了,可以关闭连接了

2. 服务端:我知道你要关闭了

3. 服务端:我发送完成了,可以关闭了

4. 客户端:我知道你发送完成了,确认关闭

三、详细过程——结合Java代码分析

(一)流程图同上

(二)步骤详解

第一次挥手(FIN)

Java代码:socket.close() 触发FIN包。

第二次挥手(ACK)

Java代码:服务器 InputStream.read() 返回 -1 表示客户端已关闭。

第三次挥手(FIN)

Java代码:服务器显式调用 socket.close()

第四次挥手(ACK)

服务器收到 ACK 后立即关闭连接。

(三)Java Socket 和 TCP 状态的关系

Java 代码TCP 状态说明
new ServerSocket(8888)LISTEN服务器监听端口,等待连接
serverSocket.accept()SYN_RECEIVED收到SYN,发送SYN+ACK
new Socket()SYN_SENT客户端发送SYN
连接建立后(accept()返回)ESTABLISHED三次握手完成,可以通信
socket.close()FIN_WAIT / CLOSE关闭连接,进入四次挥手阶段

(四)核心要点

  • 四次挥手确保双向连接安全关闭。  

  • Java的 `socket.close()` 触发FIN包,但需注意显式关闭资源。  

  • `TIME-WAIT` 是客户端的保护机制,`CLOSE-WAIT` 需防止积压。   

(五)代码见下

客户端——主动关闭

Socket socket = new Socket("localhost", 8888);
System.out.println("客户端连接成功!");// 发送数据
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println("Hello, Server!");// 主动关闭连接(第一次挥手)
socket.close(); // 发送FIN
System.out.println("客户端已关闭连接");

服务器——处理关闭 

ServerSocket serverSocket = new ServerSocket(8888);
Socket socket = serverSocket.accept();
System.out.println("客户端已连接");// 接收数据
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String message = in.readLine(); // 读取数据
System.out.println("收到客户端消息:" + message);// 检测客户端是否关闭(第二次挥手:返回ACK)
if (message == null) { // read()返回-1表示客户端已关闭System.out.println("客户端已关闭,准备关闭服务器...");
}// 服务器主动关闭(第三次挥手)
socket.close(); // 发送FIN
serverSocket.close();
System.out.println("服务器已关闭");

四、关键问题解析

(1)为什么需要四次挥手?

  • 全双工通信:因为TCP连接是双向的,关闭时需要分别关闭发送和接收通道。  

  • 客户端发送 `FIN` 表示不再发送数据,但仍可接收数据(半关闭)。  

  • 服务器需要先确认客户端的 `FIN`(第二次挥手),再发送自己的 `FIN`(第三次挥手)。

(2)TIME-WAIT状态的作用?

  • 防止最后一个ACK丢失:如果客户端直接关闭,服务器可能因未收到 `ACK` 而重发 `FIN`,导致新连接收到旧数据。  

  • 等待时间:`2MSL`(Maximum Segment Lifetime,通常2分钟),确保网络中所有残留数据包消失。

(3)CLOSE-WAIT状态积压问题

  • 如果服务器不调用 `socket.close()`,会一直处于 `CLOSE-WAIT` 状态,导致连接泄漏。  

  • 解决方案:确保服务器在检测到客户端关闭后,显式关闭Socket。

五、总结归纳概述

  • TCP四次挥手是双方双向关闭连接的过程:客户端先发FIN → 服务器回ACK → 服务器发FIN → 客户端回ACK,确保数据完整传输并安全释放资源。

  • 本质:全双工通信需分别关闭两个方向,比三次握手多一次确认

http://www.dtcms.com/a/304952.html

相关文章:

  • Java设计模式之《备忘录模式》
  • 80V降5V,输出电流4A,应用于车载充电器
  • 工厂方法模式 Factory Method Pattern
  • 监控场景视频质量异常修复:陌讯动态增强算法实战解析
  • 深入浅出设计模式——创建型模式之建造者模式 Builder
  • LangChain API 功能介绍和使用示例
  • 单卡10分钟部署MiniCPM4-0.5B:轻量级大模型本地运行指南
  • ESP8266 AT 固件
  • Linux信号量:进程同步与互斥的核心机制
  • 人形机器人指南(十四)集成
  • 248°视野里的温柔革命:当清洁成为治愈城市的艺术
  • Qt 移动应用界面设计原则
  • 智能Agent场景实战指南 Day 23 : Agent安全与隐私保护
  • C++异常捕获:为何推荐按引用(by reference)捕获?
  • 【LeetCode 热题 100】(二)双指针
  • 基于Java+SQLServer2017实现(Web)酒店客房管理系统
  • MongoDB系列教程-教程概述
  • 系统选择菜单(ubuntu grub)介绍
  • 标量子查询 外表有多少重复值决定filter次数 转化 left join
  • Python三大Web框架:FastAPI vs Flask vs Django 详解与快速入门指南
  • BreachForums 黑客论坛强势回归
  • windows软件ARM64和AMD64(x64)区别,如何查看电脑支持哪种
  • JVM易混淆名称
  • 大型微服务项目:听书——多端重复提交订单问题适配器模式实现不同支付方式的选择零钱支付逻辑
  • 爬虫逆向之瑞数五案例:某某医学院(补环境,联调)
  • 适配器模式的三种C++实现
  • 宠物经济行业研究系列报告
  • electron-vite 动态加载脚本 实现动态插件
  • 如何为你的WordPress网站选择合适的安全插件
  • 【效率工具】255款工作计划表格Excel电子版模板:总结日月周报日历安排提醒时间管理