计算机网络-断开连接的四次挥手底层细节

文章目录

  • [1. TCP四次挥手过程](#1. TCP四次挥手过程)
  • [2. 为什么四次挥手中间两次不能变成一次?](#2. 为什么四次挥手中间两次不能变成一次?)
  • [3. 第二次和第三次挥手能合并吗?](#3. 第二次和第三次挥手能合并吗?)
  • [4. 第三次挥手一直没发,会发生什么?](#4. 第三次挥手一直没发,会发生什么?)
  • [5. 第二次和第三次挥手之间主动断开的那端能干什么?](#5. 第二次和第三次挥手之间主动断开的那端能干什么?)
  • [6. 断开连接时,客户端fin包丢失,服务端的状态是什么?](#6. 断开连接时,客户端fin包丢失,服务端的状态是什么?)
  • [7. 为什么四次挥手之后要等2MSL?](#7. 为什么四次挥手之后要等2MSL?)
  • [8. 服务端出现大量的timewait有哪些原因?](#8. 服务端出现大量的timewait有哪些原因?)

1. TCP四次挥手过程

  1. 第一次挥手:客户端发送FIN
  • 客户端打算关闭连接,向服务端发送一个FIN。
  • 状态变化:客户端状态变为FIN-WAIT1。这表示客户端没有数据发送了。但仍然可以接收数据。
  1. 第二次挥手:服务端,发送ACK
  • 服务端接收到FIN后返回一个ACK确认报文。
  • 状态变化:服务端进入CLOSE-WAIT状态。客户端收到确认后进入,FIN-WAIT2状态。
  • 意思:此时处于半关闭状态,服务端可能还有未发完的数据,需要继续发送。
  1. 第三次挥手:服务端发送FIN
  • 当服务端处理完所有数据,准备好关闭连接时,向客户端发送FIN报文段。是。
  • 状态变化。服务端进入LAST-ACK状态。
  1. 第四次挥手:客户端发送ACK
  • 客户端收到FIN后,向服务端发送最后一个ACK确认报文。
  • 状态变化:客户端进入TIME-WAIT状态。服务端收到ACK后,直接进入CLOSE的状态。
  • 最终关闭:客户端在经过2MSL(最大报文生存时间后),自动进入CLOSE的状态。

底层原理:

  • 客户端发送fin包,会携带一个EOF数据。一旦在服务端读取到该符号,read()或recv()就会返回0。
  • 实际操作中,read()==0就是应用程序判断对端已关闭连接的标准信号。
  • 操作系统内核会立刻自动回复一个ACK。
  • 服务端发送的FIN,由应用程序决定什么时候发送。

2. 为什么四次挥手中间两次不能变成一次?

服务器接收到客户端的FIN报文后,内核会返回一个ACK报文,但是服务端应用程序可能还有未发送完的数据,所以并不能立马发送FIN报文。而是将FIN报文的控制权,交给应用程序。

3. 第二次和第三次挥手能合并吗?

当被动关闭方,在TCP挥手过程中,没有数据要发送,并且开启了TCP延迟确认机制,那么第二次和第三次挥手可以合并。

  • TCP延迟确认:收到数据后不立刻发送ack确认包,而是启动一个小定时器,通常最多等两百毫秒。如果等待期间自己正好有数据要发送给对方,就将该ACK合并到数据包里一起发走。

4. 第三次挥手一直没发,会发生什么?

第二次挥手后,主动方会处于FIN-WAIT2状态。就表示主动方发送通道已关闭,等待对方发送FIN报文,关闭对方的发送通道。

这时如果连接是用shutdown函数关闭的,连接可以一直处于FIN-WAIT2状态。因为它可能还可以发送或接收数据。对于close函数关闭的,故而连接由于无法再发送和接收数据,所以这个状态不可以持续太久,而tcp-fin-timeout控制了这个状态下连接时长,默认是六十秒。

5. 第二次和第三次挥手之间主动断开的那端能干什么?

如果主动断开的那一方式调用了shutdown函数来关闭连接的设置。关闭了发送能力,没有关闭接收能力,那么主动断开一方在第二次和第三次挥手之间还可以接收数据。

6. 断开连接时,客户端fin包丢失,服务端的状态是什么?

  • 如果第一次挥手丢失了。那么客户端迟迟收不到对方的AC K的话,也就会触发超时重传机制。重传次数由TCP_ORPHAN_RETRIES参数控制。
  • 当客户端重传FIN报文超过次数后就不会再发送fin报文,而是等待上一次超时重传时间的两倍。如果还没有收到第二次挥手,那么客户端直接进入到CLOSE状态,而服务端还是ESTABLISHE的状态。

7. 为什么四次挥手之后要等2MSL?

MSL是报文在网络中存活最长时间。

  1. 确保沿街的可靠关闭兜底(最后一次ACK丢失)

    为了确保客户端最后发出的ACK能够顺利到达服务端,如果这个ACK丢失,服务端会超时重发。第三次握手的报文2MSL刚好是一个报文,在网络中一来一回最长时间。等待2MSL能确保客户端有足够时间,接收到可能重传的FIN并发送ACK,从而让双方都正常关闭。

  2. 防止历史过期报文干扰新连接

    经过2MSL的时间可以确保本次TCP连接中产生所有报文都在网络中彻底消亡。这样就能避免后续使用相同IP和端口号建立新连接时被就连接的残余报文干扰。

8. 服务端出现大量的timewait有哪些原因?

根本原因:服务端在大量的主动关闭连接。

  1. 大量的短连接
  • 未开启HTTP长连接(keep-Alive),短连接每次请求都要经历这样的过程:建立TCP->请求资源->响应资源->释放连接。
  1. 第二个场景:长连接超时
  • HTTP长连接可以在同一个TCP连接上接收和发送多个HTTP请求/应答,避免了连接建立和释放的开销。
  • Web服务软件一般会提供一个定时器。定时器假如设置时长六十秒,如果客户端在六十秒内都没有再次发起新的请求。定时器时间一到,就会触发回调函数来关闭连接,那么此时服务端上就会出现TIME_WAIT状态的连接。
  1. 第三个场景:HTTP长连接的请求数量达到上限
  • Web服务端通常会有个参数来定义一条HTTP长连接最大能处理请求数量。当超过数量时就会主动关闭连接。
  • 比如nginx的keepalive_requests这个参数,长连接会有一个计数器记录处理请求数量如果超过这个参数,就会主动关闭这个长连接。
  • 该默认值一般为100,但如果是QPS比较高的场景。比如超过一万QPS,甚至更高时,这时候,就会频繁关闭连接,那么此时服务器上就会出现大量的TIME-WAIT的状态。
  • 解决方法调大nginx的keepalive-requests参数。
相关推荐
醉城夜风~4 小时前
Java详解经典算法题:接雨水(三种实现方案+原理剖析)
java·开发语言·算法
数智化转型推荐官5 小时前
2026统一身份管理系统五大发展趋势解读
java·运维·微服务
看菜鸡互5 小时前
探索用 SlideML 让大模型生成 PPT 的实验方法
java·运维
2603_954708316 小时前
全维度容错设计,打造微电网安全运行屏障
服务器·网络·数据库·人工智能·分布式·安全
青岛前景互联信息技术有限公司6 小时前
以新标准为底座,前景互联打造高危场景智能接处警新体系
大数据·网络·人工智能
大飞记Python6 小时前
Linux命令速查手册(测试开发4年实战总结,附PDF)
linux·网络·pdf
AFinalStone6 小时前
Android 7系统网络(四)Native层(下)—netd Controller详解
android·网络
Sirius Wu7 小时前
OpenClaw(UpClaw)三层Tool全链路治理深度详解
网络·人工智能·架构·aigc
程序员张37 小时前
SpringBoot集成BCrypt密码加密库
java·spring boot·后端
闲猫7 小时前
Spring AI Agentic 模式(第1部分):Agent Skills——模块化、可复用的能力
java·人工智能·spring