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

三次握手,四次挥手:你的 connect() 和 close() 在 TCP 栈里经历了什么?

你用 Java 的Socket连接服务器一行new Socket(host, port)就搞定了。但在这行代码背后操作系统内核为你悄悄完成了三次握手SYN、SYNACK、ACK。当你关闭连接时又是四次挥手FIN、ACK、FIN、ACK。每一个状态转变都对应着你代码里的connect()、accept()、close()。而TIME_WAIT状态更是让无数后端工程师抓狂的“端口被占用”元凶。大家好我是Evan一个用netstat -an | grep TIME_WAIT排查过线上服务端口耗尽的 JavaAI 学生。今天我从 TCP 的三次握手和四次挥手讲起带你看看 Java 的Socket、ServerSocket和close()背后到底发生了什么。读完这篇你不仅能画出 TCP 状态机还能理解为什么高并发下会出现Address already in use。 写在前面大二学计网我死记硬背了三次握手和四次挥手的图但总觉得那是路由器和交换机的事跟我的 Java 代码无关。直到我在知识汇教育平台做一个长连接服务压测时频繁报BindException: Address already in use查了半天发现是TIME_WAIT堆积。那一刻我才明白每一次你调用close()内核都帮你维护了一个定时器。这篇博客我就用 Java 开发者的语言把 TCP 握手挥手的状态机讲透。一、三次握手建立连接的“礼尚往来”1.1 为什么需要三次两次不行吗三次握手的核心目的让双方确认自己的发送和接收能力正常并且协商初始序列号ISN。两次握手无法防止已过期的连接请求突然到达造成的混乱。1.2 握手过程与状态转移Java 视角new Socket(localhost, 8080)会阻塞直到三次握手完成或超时。ServerSocket.accept()在三次握手完成后才会返回一个新的Socket对象。1.3connect()超时与accept()阻塞Socket socket new Socket(); socket.connect(new InetSocketAddress(host, 8080), 2000); // 超时 2 秒如果在规定时间内没完成握手抛出SocketTimeoutException。而ServerSocket.accept()会一直阻塞直到有客户端完成三次握手。二、四次挥手优雅地告别2.1 为什么需要四次因为 TCP 是全双工的每一方都需要单独关闭自己的发送通道。主动关闭方发送FIN被动方回复ACK然后被动方也发送FIN主动方回复ACK。2.2close()与TIME_WAIT主动关闭方谁先调用close()会进入TIME_WAIT状态持续2 倍 MSLMaximum Segment Lifetime通常 30 秒到 2 分钟。为什么要有TIME_WAIT确保最后一个ACK能被对方收到如果对方没收到会重发FIN。让网络上残留的旧数据包消失避免影响新连接。问题高并发短连接场景如压测大量TIME_WAIT会占用本地端口导致Address already in use。Java 中的对应socket.close(); // 触发 TCP 四次挥手的主动关闭2.3SO_REUSEADDR选项可以通过设置 socket 选项允许重用TIME_WAIT状态的端口ServerSocket server new ServerSocket(); server.setReuseAddress(true); server.bind(new InetSocketAddress(port));但要注意风险可能收到老连接的残留数据。三、常见开发场景与排查命令3.1 查看 TCP 连接状态netstat -an | grep -E ESTABLISHED|TIME_WAIT|CLOSE_WAITESTABLISHED正常通信的连接。TIME_WAIT主动关闭方等待 2MSL过多会影响端口。CLOSE_WAIT被动关闭方收到 FIN 后未调用close()代码 bug 常见服务端忘记关闭连接。CLOSE_WAIT 泄漏如果你的 Java 服务不断出现CLOSE_WAIT说明你没有在 finally 块里关闭 socket 或 channel。3.2 调整系统参数缓解TIME_WAITLinux 下可以修改# 开启快速回收不推荐新内核 net.ipv4.tcp_tw_reuse 1 net.ipv4.tcp_tw_recycle 0 # 已废弃 # 减少 TIME_WAIT 持续时间不建议低于 30 秒 net.ipv4.tcp_fin_timeout 30更推荐使用连接池如 HikariCP、HttpClient 连接池复用连接避免频繁创建和关闭。3.3ServerSocket.accept()与多线程每个新连接accept()后通常交给线程池处理别忘了在 finally 中关闭SocketSocket client server.accept(); executor.submit(() - { try { // 处理请求 } finally { client.close(); // 触发四次挥手 } });四、常见问题与陷阱4.1 服务端大量CLOSE_WAIT原因服务端收到客户端 FIN 后没有调用close()。典型错误线程池处理请求时只关闭了输入输出流但没关闭 socket 本身。解决使用 try-with-resources 或确保 finally 中关闭 socket。4.2 客户端大量TIME_WAIT原因短连接场景客户端主动关闭。解决改用长连接HTTP Keep-Alive或连接池。4.3connect超时 vsread超时connect超时三次握手未完成。read超时连接已建立但对方迟迟不发送数据setSoTimeout。4.4Socket的close()与shutdownOutput()close()完全关闭发送 FIN。shutdownOutput()半关闭只关闭输出方向仍可读。常用于通知对端“我不再写数据”。 总结核心结论TCP 握手/挥手是可靠传输的基础每个状态都对应内核行为。Java 开发者要特别注意CLOSE_WAIT忘记关闭和TIME_WAIT短连接过多。用连接池、复用连接、合理设置SO_REUSEADDR可以缓解端口耗尽问题。思考题你写了一个 HTTP 服务器用ServerSocket.accept()接收请求每次处理完请求后调用socket.close()。压测 10000 个短连接后发现客户端报BindException: Address already in use。你用netstat -an | grep TIME_WAIT看到大量TIME_WAIT连接都是客户端端口。问题为什么客户端会大量TIME_WAIT如何在不修改内核参数的情况下减少这种现象欢迎在评论区留下你的方案 —— 下一篇我会聊聊“UDP 的无连接特性DNS 查询为什么喜欢用 UDP”
http://www.rkmt.cn/news/1396785.html

相关文章:

  • OpenKore终极指南:5分钟快速掌握RO游戏自动化辅助
  • 目前好用的 AI 视频创作平台有哪些?AI 视频生成不排队工具推荐
  • 基于Multisim的多层电梯控制系统设计与仿真
  • 2026财务人员提升工作能力的实用方法
  • 如何用淘金币自动化脚本在5分钟内完成每日任务:新手完整指南
  • 应对Turnitin严查:英文论文AI率从80%降至10%的无痕攻略(附工具测评)
  • PubLayNet背后的技术:自动标注算法与质量保证机制
  • 为什么选择XPlaneConnect:NASA开源飞行模拟控制工具终极指南
  • 流处理优化:提高实时数据处理效率
  • SSH密钥交换失败Kex_exchange_identification原因与修复
  • 零样本分类最佳实践:用deberta-v3-base-zeroshot-v2.0处理多标签任务
  • 使用alexa-app框架构建多语言Alexa技能:国际化支持详解
  • 深耕高端家装,宝鹿散热器以品质守护温暖家居 - 资讯纵览
  • 复用采集VS同步采集:数据采集卡的核心差异
  • 鹅厂二面:Function Calling、Skill、MCP 这三个概念有什么区别?
  • JWT安全实战手册:从alg=none漏洞到零信任加固
  • 北京地区2026年京牌租赁注意事项:郭子车务理性分析 - 企业深度横评dyy6420
  • 跨语言词嵌入与随机梯度下降:低资源语言人格预测的工程实践
  • 【图像检测】基于交互多模型IMM过滤进行自动驾驶异常行为检测附Matlab代码
  • 龙虾都还没养好,大家又聊起了养马?带你看懂OpenClaw与Hermes Agent的区别
  • OpenOOD脚本系统:100+脚本如何简化实验复现流程 [特殊字符]
  • Codex自我蒸馏玩法火了!OpenAI员工亲授:复制粘贴就能让AI消灭重复劳动
  • 联邦学习应对非独立同分布数据:基于CVAE的隐私保护数据增强方案
  • STGCN与度量学习:AI如何精准评估脑瘫儿童步态功能
  • 《Foundation 选项卡:设计与实现指南》
  • Kubernetes性能优化与资源管理:提升集群运行效率
  • 热红外相机标定+红外图像温度反演+作物水分应力指数CWSI计算无人机热红外遥感→反演地表温度→评估植被干旱水分状况附matlab代码
  • 高效精简答辩筹备!Okbiye 智能 AI PPT 助力毕业生完成论文宣讲展示
  • 【JavaSE - 网络部分07】TCP 收尾:面向字节流(粘包问题)与异常场景处理【传输层】
  • 叠氮酸介绍