TCP连接,没有打开keepalive选项,没有数据交互,一端突然断电和一端的进程crash了,这两种情况有什么区别呢?

这个属于TCP异常断开连接的场景

这个问题有几个关键词:

没有开启keepalive

一直没有数据交互;

进程崩溃;

主机崩溃;

正文

我们先来认识认识什么是TCPkeepalive呢?

这东西其实就是TCP的保活机制,它的工作原理我之前的文章写过,这里就直接贴下以前的内容。

 

如果两端的TCP连接一直没有数据交互,达到了触发TCP保活机制的条件,那么内核里的TCP协议栈就会发送探测报文。

如果对端程序是正常工作的。当TCP保活的探测报文发送给对端,对端会正常响应,这样TCP保活时间会被重置,等待下一个TCP保活时间的到来。

如果对端主机崩溃,或对端由于其他原因导致报文不可达。当TCP保活的探测报文发送给对端后,石沉大海,没有响应,连续几次,达到保活探测次数后,TCP会报告该TCP连接已经死亡

所以,TCP保活机制可以在双方没有数据交互的情况,通过探测报文,来确定对方的TCP连接是否存活。

注意,应用程序若想使用TCP保活机制需要通过socket接口设置SO_KEEPALIVE选项才能够生效,如果没有设置,那么就无法使用TCP保活机制。

知道了TCPkeepalive作用,我们再回过头看题目中的「主机崩溃」这种情况。

在没有开启TCPkeepalive,且双方一直没有数据交互的情况下,如果客户端的「主机崩溃」了,会发生什么。

如果客户端主机崩溃了,服务端是无法感知到的,在加上服务端没有开启TCPkeepalive,又没有数据交互的情况下,服务端的TCP连接将会一直处于ESTABLISHED连接状态,直到服务端重启进程。

所以,我们可以得知一个点。

在没有使用TCP保活机制,且双方不传输数据的情况下,一方的TCP连接处在ESTABLISHED状态时,并不代表另一方的TCP连接还一定是正常的。

那题目中的「进程崩溃」的情况呢?

我自己做了个实验,使用kill-9来模拟进程崩溃的情况,发现kill掉进程后,服务端会发送FIN报文,与客户端进行四次挥手

所以,即使没有开启TCPkeepalive,且双方也没有数据交互的情况下,如果其中一方的进程发生了崩溃,这个过程操作系统是可以感知的到的,于是就会发送FIN报文给对方,然后与对方进行TCP四次挥手。

以上就是对这个面试题的回答。

这面试题其实在变相考察TCP保活机制的作用。

接下来我们看看在「有数据传输」的场景下的一些异常情况:

第一种,客户端主机宕机,又迅速重启,会发生什么?

第二种,客户端主机宕机,一直没有重启,会发生什么?

客户端主机宕机,又迅速重启

在客户端主机宕机后,服务端向客户端发送的报文会得不到任何的响应,在一定时长后,服务端就会触发超时重传机制,重传未得到响应的报文。

服务端重传报文的过程中,刚好客户端主机重启完成,这时客户端的内核就会接收重传的报文,:

如果客户端主机上没有进程监听该TCP报文的目标端口号,由于找不到目标端口,客户端内核就会回复RST报文,重置该TCP连接

如果客户端主机上进程监听该TCP报文的目标端口号,由于客户端主机重启后,之前的TCP连接的数据结构已经丢失了,客户端内核里协议栈会发现找不到该TCP连接的socket结构体,于是就会回复RST报文,重置该TCP连接。

所以,只要有一方重启完成后,收到之前TCP连接的报文,都会回复RST报文,以断开连接。

客户端主机宕机,一直没有重启

这种情况,服务端超时重传报文的次数达到一定阈值后,内核就会判定出该TCP有问题,然后通过Socket接口告诉应用程序该TCP连接出问题了。

那具体重传几次呢?

Linux系统中,提供了一个叫tcp_retries2配置项,默认值是15,如下图:

这个内核参数是控制,在TCP连接建立的情况下,超时重传的最大次数。

不过tcp_retries2设置了15次,并不代表TCP超时重传了15次才会通知应用程序终止该TCP连接,内核还会基于「最大超时时间」来判定。

每一轮的超时时间都是倍数增长的,比如第一次触发超时重传是在2s后,第二次则是在4s后,第三次则是8s后,以此类推。

内核会根据tcp_retries2设置的值,计算出一个最大超时时间。

在重传报文且一直没有收到对方响应的情况时,先达到「最大重传次数」或者「最大超时时间」这两个的其中一个条件后,就会停止重传

最后说句。

TCP牛逼,啥异常都考虑到了

原文链接:https://iflow.uc.cn/webview/news?app=uc-iflow&aid=10896237518468038917&cid=100&zzd_from=uc-iflow&recoid=11387317157362882584&rd_type=share&sp_gz=0&pagetype=share&btifl=100&uc_share_depth=1&uc_param_str=dndsfrvesvntnwpfgipc

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值