【JavaEE初阶】TCP核心机制10——异常情况的处理
TCP在通信过程中可能会出现特殊情况~
情况一:某个进程崩溃了
- 进程崩溃和主动退出没有本质区别,都是进程释放(回收文件描述符表)
- ->也就是文件描述符表的每个资源都调用socket.close
- ->也就是FIN,触发四次挥手
- ->四次挥手不依赖进程,关键在于连接是否还在
- ->因此,进程虽然没有了,但TCP的连接信息还在,因此四次挥手还是可以正常运行的2
- ->如果对方不给回应->TIME_WAIT状态->FIN重传->超时->自动断开连接
情况二:主机关机了
正常流程的关机,本质上就是杀死所有用户进程->和程序崩溃差不多
关机需要一定时间
如果一定时间内,四次挥手正常挥完,就正常关机
那如果没有挥完呢?
四次挥手的过程
- 假设B的FIN来得太迟了,导致A已经关机完成了
- 意味着B的FIn不会收到ACK
- B经过几次重传,对端都没有返回ACK
- B就会认为对端出现了严重的网络问题
- 此时B会主动放弃连接(B把A的信息删了)
- 因此,B最终仍然可以把连接释放掉
情况三:主机掉电了
就是台式机直接拔电源的情况->不要随便拔,很伤硬盘的
为什么伤硬盘:
- 因为硬盘是机械结构,盘片会高速运转
- 突然拔电,盘片由于惯性继续在转,在磁盘上写了一堆乱七八糟的数据
如果是接收方掉电
接收方掉电
- A突然掉电
- B后续发来的数据都没有ACK回应了
- B触发超时重传
- 如果重传达到一定次数后 还是收不到ACK,就会触发“重置TCP连接”操作
- B会主动发一个“复位报文”(重头开始,既往不咎)
- 如果RST也收不到ACK
- B只能单方面释放连接了
如果是发送方掉电
- B突然发现,A没有声音了
- 此时B区分不了A是暂时休息一下,还是挂了
- B只能继续等,但也不是无限等
- B等待一定时间后,就会给A发送一个特殊的报文“心跳包”
- 心跳包:不携带业务数据,只为了触发ACK
- 如果对方有心跳,就继续正常等待
- 如果没有心跳,就触发RST(复位报文)
- 如果还是没有回应,B只能单方面释放连接了
写到这里突然想说一句:果然连计算机都受不了冷暴力
关于心跳包:
- 是周期性的,如果没有心跳了,就认为对方挂了
TCP的保活机制
- 在分布式系统中,心跳包 的思想,使用非常广泛,
- 但是TCP的心跳周期太长了——>是分钟级别 的
- 虽然TCP内置了心跳包,但是在实际开发中,通常还是会在应用层重新实现心跳包效果
- 因为程序员希望心跳周期是秒级,甚至毫秒级的,
- 这样就能及时发现对端是否正常存活,从而触发一下后续的操作
分布式系统
- 分布式系统是采取负载均衡的方式处理请求,
- 也就是用 多个功能相同的业务服务器 来处理请求,
- 如果某个业务服务器突然挂了,
- 心跳包就能在毫秒级的时间内发现这里的问题,
- 从而让入口及时把流量切换到其他机器上
情况四:网线断开了
- 站在A的视角,就和上面“接收方掉电”是一样的情况
- 站在B的视角,就和上面“发送方掉电”是一样的情况
- 最终都是可以释放资源的
好啦!TCP的十大核心机制终于讲完啦!
下节我会出一个TCP十大核心机制的大合集!敬请期待!
END✿✿ヽ(°▽°)ノ✿






