(学习笔记-TCP断开连接)一端断电和进程崩溃有什么区别?

可以看一下之前的一篇学习笔记,里面提到过类似情况。

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

  • 如果对端程序是正常工作的。当TCP保活的探测报文发送给对端,对端会正常响应,这样TCP保活时间会被重置,等待下一个TCP保活时间的到来。
  • 如果对端主机崩溃,或对端由于其他原因导致报文不可达。当TCP保活的探测报文发送给对端后,石沉大海,没有响应,连续几次达到保活探测次数后,TCP会报告该TCP连接已经死亡

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


主机崩溃

前提条件:没有开启 TCP keepalive,且双方都没有数据发送

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

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


进程崩溃

TCP连接信息是由内核维护的,所以当服务端的进程崩溃后,内核需要回收该进程所有的TCP连接资源,于是内核会发送一次FIN挥手报文,后续的挥手过程也是在内核完成的,并不需要进程的参与,所以即使服务端进程崩溃了,还是能与客户端完成TCP四次挥手


有数据传输的场景

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

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

服务端重传报文的过程中,客户端主机完成重启后,客户端的内核就会重新接收重传的报文,然后根据报文的信息传递给对应的进程:

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

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

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

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

TCP的数据报文具体重传几次?

在linux系统中,提供一个叫做tcp_retries2的配置项,默认值是15。这个内核参数是控制TCP连接建立的情况下,超时重传的最大次数。

 

不过tcp_retries设置了15次,并不代表TCP超时重传了15次才会通知应用程序终止该TCP连接,内核会根据tcp_retries2设置的值,计算出一个timeout(如果tcp_retries2 = 15 ,timeout = 924600ms),如果重传间隔超过了这个timeout,则认为超过了阈值,就会停止重传,然后就会断开TCP连接。

 

在发生超时重传的过程中,每一轮的超时时间(RTO)是倍数增长的,如果第一轮RTO是200ms,那么第二轮RTO是400ms,第三轮RTO是800ms. . .\

RTO是基于RTT(一个包的往返时间)来计算的,如果RTT较大,那么计算出来的RTO就越大,那么经过几轮的重传后,很快就到达上面的timeout值

最小RTO和最大RTO在Linux内核中已经定义好了:

#define TCP_RTO_MAX ((unsigned)(120*HZ))
#define TCP_RTO_MIN ((unsigned)(HZ/5))

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值