目录
tcp异常情况
在通信过程中:
进程终止
连接与进程不直接相关,它是和文件绑在一起的
- 每建立一个套接字,就要新增一个文件描述符
但是,文件的生命周期是随进程的
- 所以,一旦进程退出,套接字是需要被释放的
注意:
- 无论是正常/异常终止,对于os来说,都只是杀掉了一个进程,只是可能有异常的要多设置一些标志位啥的,但大体上没有区别
- 进程的异常与否,与其他模块无关,os也不希望一个模块的异常会影响到其他模块
- 所以,其他模块会正常处理进程退出(不管是什么情况,人家不管)
- 也就是os帮忙向对方主机发送要断开连接的需求,正常开始四次挥手,连接正常断开
机器重启
重启,也就是机器关闭前,需要先杀掉正在运行的进程
- 而[正在进行网络通信流程]的进程需要断开连接
- 也就是按照进程终止的流程走
这也就是为什么有时候关机比较久
- 因为正在运行的进程需要正确释放资源,比如网络连接
机器掉电/网线断开
这属于不可抗力
对于机器掉电:
- 一旦发生,os都没了,也就没机会告诉对方自己要断开了,也就没法开始四次挥手
- 机器都停了,上面的资源也就自动释放了
对于网线断开:
- 客户端应用层可以检测到本机的网络变化
- 网络都没了,自然也就没必要继续维护[因网络通信而存在的连接]了
但是,对方可能认为连接还存在
如果客户端此时网络恢复/机器重新启动,又开始通信,这时:
- 客户端:无连接状态
- 服务端:连接正常
- 这就形成了连接认知不一致的问题
- 服务端会主动发送带有RESET的报文,重新建立连接
那如果客户端一直都没有再重新通信呢?对方维持的这个连接会一直存在吗?
- 自然不会
- tcp有保活机制,如果客户端一段时间内一直不通信,会主动询问
- 如果多次询问无果(也就是没有应答),服务端就认为对方已经断开连接,于是释放自己这边的连接
应用层
应用层的某些协议 , 也有一些这样的检测机制
- 比如在http长连接中, 也会定期检测对方的状态
- 就像在qq因网络断线之后, 它会定期尝试重新连接