首页 > 其他分享 >[转载]TCP keepalive的详解(解惑)

[转载]TCP keepalive的详解(解惑)

时间:2024-05-27 18:34:01浏览次数:23  
标签:probes tcp SO TCP 解惑 keepalive KEEPALIVE

原文出自于https://www.cnblogs.com/lanyangsh/p/10926806.html

TCP是面向连接的,一般情况,两端的应用程序可以通过发送和接收数据得知对端的存活。
当两端的应用程序都没有数据发送和接收时,如何判断连接是否正常呢?

这就是SO_KEEPALIVE的作用。

1. SO_KEEPALIVE 的作用

1.1 SO_KEEPALIVE的定义

SO_KEEPALIVE用于开启或者关闭保活探测,默认情况下是关闭的。

SO_KEEPALIVE开启时,可以保持连接检测对方主机是否崩溃,避免(服务器)永远阻塞于TCP连接的输入。

相关的属性包括:

tcp_keepalive_time、tcp_keepalive_probes、tcp_keepalive_intvl。

tcp_keepalive_intvl (integer; default: 75; since Linux 2.4)
      The number of seconds between TCP keep-alive probes.

tcp_keepalive_probes (integer; default: 9; since Linux 2.2)
      The maximum number of TCP keep-alive probes to send before
      giving up and killing the connection if no response is
      obtained from the other end.

tcp_keepalive_time (integer; default: 7200; since Linux 2.2)
      The number of seconds a connection needs to be idle before TCP
      begins sending out keep-alive probes.  Keep-alives are sent
      only when the SO_KEEPALIVE socket option is enabled.  The
      default value is 7200 seconds (2 hours).  An idle connection
      is terminated after approximately an additional 11 minutes (9
      probes an interval of 75 seconds apart) when keep-alive is
      enabled.

      Note that underlying connection tracking mechanisms and
      application timeouts may be much shorter.

这些属性可以在/proc/sys/net/ipv4/下查看:

cat /proc/sys/net/ipv4/tcp_keepalive_time
7200

cat /proc/sys/net/ipv4/tcp_keepalive_probes
9

cat /proc/sys/net/ipv4/tcp_keepalive_intvl
75

也可以通过命令行查看:

sudo sysctl -a | grep keepalive

net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75

1.2 连接探活的过程

开启SO_KEEPALIVE后,如果2小时内在此套接口的任一方向都没有数据交换,TCP就自动给对方发一个保持存活探测分节(keepalive probe)。这是一个对方必须响应的TCP分节.

它会导致以下三种情况:

对方接收一切正常:以期望的ACK响应。2小时后,TCP将发出另一个探测分节。
对方已崩溃且已重新启动:以RST响应。套接口的待处理错误被置为ECONNRESET,套接 口本身则被关闭。
对方无任何响应:源自berkeley的TCP发送另外8个探测分节,相隔75秒一个,试图得到一个响应。一共尝试9次,即在发出第一个探测分节11分钟 15秒后若仍无响应就放弃。套接口的待处理错误被置为ETIMEOUT,套接口本身则被关闭。如ICMP错误是“host unreachable(主机不可达)”,说明对方主机并没有崩溃,但是不可达,这种情况下待处理错误被置为 EHOSTUNREACH。
根据上面的介绍我们可以知道对端以一种非优雅的方式断开连接的时候,我们可以设置SO_KEEPALIVE属性使得我们在2小时以后发现对方的TCP连接是否依然存在。

int keepAlive = 1;

setsockopt(listenfd, SOL_SOCKET, SO_KEEPALIVE, (void*)&keepAlive, sizeof(keepAlive));

如果我们不能接受如此之长的等待时间,怎么办?

2.设置TCP KEEPALIVE

上面提到,SO_KEEPALIVE默认的时间间隔太长,不利于应用程序检测连接状态。

解决方法有2种:

全局设置

针对单个连接设置

2.1 全局设置

在Linux中我们可以通过修改 /etc/sysctl.conf 的全局配置:

net.ipv4.tcp_keepalive_time=7200
net.ipv4.tcp_keepalive_intvl=75
net.ipv4.tcp_keepalive_probes=9

添加上面的配置后输入 sysctl -p 使其生效,
你可以使用命令来查看当前的默认配置

sysctl -a | grep keepalive 

如果应用中已经设置SO_KEEPALIVE,程序不用重启,内核直接生效.

这种方法设置的全局的参数,针对整个系统生效,对单个socket的设置不够友好。

2.2 针对单个连接设置

我们可以使用TCP的TCP_KEEPCNT、TCP_KEEPIDLE、TCP_KEEPINTVL3个选项。
这些选项是连接级别的,每个socket都可以设置这些属性。

这些选项的定义,可以通过man查看。


man 7 tcp
socket option:

TCP_KEEPCNT (since Linux 2.4)
      The maximum number of keepalive probes TCP should send before
      dropping the connection.  This option should not be used in
      code intended to be portable.
      关闭一个非活跃连接之前的最大重试次数。
      该选项不具备可移植性。

TCP_KEEPIDLE (since Linux 2.4)
      The time (in seconds) the connection needs to remain idle
      before TCP starts sending keepalive probes, if the socket
      option SO_KEEPALIVE has been set on this socket.  This option
      should not be used in code intended to be portable.
      设置连接上如果没有数据发送的话,多久后发送keepalive探测分组,单位是秒
      该选项不具备可移植性。

TCP_KEEPINTVL (since Linux 2.4)
      The time (in seconds) between individual keepalive probes.
      This option should not be used in code intended to be
      portable.
      前后两次探测之间的时间间隔,单位是秒
      该选项不具备可移植性。

代码层面的设置步骤:


int keepAlive = 1;    // 非0值,开启keepalive属性

int keepIdle = 60;    // 如该连接在60秒内没有任何数据往来,则进行此TCP层的探测

int keepInterval = 5; // 探测发包间隔为5秒

int keepCount = 3;        // 尝试探测的最多次数

// 开启探活
setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));

setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));

setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));

setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount) 

3.为什么应用层需要heart beat/心跳包?

通过上面的介绍,感觉TCP keepalive已经很牛逼了,但为什么还会提到应用层的心跳呢?

目前了解的原因包括两个:

TCP keepalive处于传输层,由操作系统负责,能够判断进程存在,网络通畅,但无法判断进程阻塞或死锁等问题。
客户端与服务器之间有四层代理或负载均衡,即在传输层之上的代理,只有传输层以上的数据才被转发,例如socks5等
所以,基于以上原因,有时候还是需要应用程序自己去设计心跳规则的。
可以服务端负责周期发送心跳包,检测客户端,也可以客户端负责发送心跳包,或者服服务端和客户端同时发送心跳包。

可以根据具体的应用场景进行设计。

标签:probes,tcp,SO,TCP,解惑,keepalive,KEEPALIVE
From: https://www.cnblogs.com/celticzy/p/18216187

相关文章

  • TCP_UNACCEPTABLE_14: [close-wait] out-of-wdw SEQ | unacceptable ACK -> ACK (seq,
    测试目的:验证TCP在CLOSE-WAIT状态下,接收到一个窗口外的序列号或不可接受的ACK号的段时,是否能够返回一个带有正确的序列号和ACK号的ACK段,并保持在相同的状态。描述:在TCP连接的CLOSE-WAIT状态下,如果接收到一个序列号超出当前窗口或ACK号不可接受的段,TCP必须回应一个空的ACK......
  • H3CNE-7-TCP和UDP协议
    TCP和UDP协议TCP:可靠传输,面向连接--------速度慢,准确性高UDP:不可靠传输,非面向连接--------速度快,但准确性差面向连接:如果某应用层协议的四层使用TCP端口,那么正式的数据报文传输之前,需要先建立连接,只有建立完连接之后,才可以传输数据。TCP三次握手......
  • TCP/IP体系模型简介
    一、TCP/IP概念TCP(TransmissionControlProtocol传输控制协议):是一种面向连接的、可靠的传输层协议。通过三次握手建立连接,确保连接的可靠建立。对数据进行有序传输,并具有确认机制和重传机制来保证数据的完整性。提供流量控制和拥塞控制功能,以适应不同的网络状况。IP(Int......
  • Modbus TCP转Profinet网关配置案例
    本案例采用XD-ETHPN20网关做为ModbusTCP通信协议设备与Profinet通信协议设备连接的桥梁。ModbusTCP是一种基于TCP/IP协议的工业通信协议,而Profinet则是用于太网通信的协议。ModbusTCP转Profinet网关可实现这两种不同协议之间的数据交换和传输,极大地方便了工业生产现场的自动化......
  • qt一个线程管理的tcp
    写一个在x线程中管理的tcp#include<QThread>#include<QTcpSocket>#include<QObject>#include<QNetworkProxy>classTcpSocketController:publicQTcpSocket{Q_OBJECTpublic:TcpSocketController(QObject*parent=nullptr):QTcpSoc......
  • 【阿里前端面试题】客户端和服务器交互,为什么选用tcp协议建立链接?超详细,建议关注收藏
    大家好,我是“寻找DX3906”。每天进步一点。日积月累,有朝一日定会厚积薄发前言        在上一篇文章中《【阿里前端面试题】浏览器的加载渲染过程,超详细》中描述:浏览器使用IP地址与服务器建立连接,通常是通过TCP(传输控制协议)。那为什么要使用TCP协议建立链接呢......
  • 一台服务器​最大并发 tcp 连接数多少?65535?
    首先,问题中描述的65535个连接指的是客户端连接数的限制。在tcp应用中,server事先在某个固定端口监听,client主动发起连接,经过三次握手后建立tcp连接。那么对单机,其最大并发tcp连接数是多少呢?如何标识一个TCP连接在确定最大连接数之前,先来看看系统如何标识一个tcp连接。系统用一个......
  • 三次握手和四次挥手、UDP、TCP、粘包问题、模块回顾
    【一】三次握手和四次挥手【1】TCP协议的三次握手和四次挥手TCP协议位于osi七层协议中的传输层(1)使用三次握手来建立连接一次握手:客户端发送带有SYN(SEQ=x)标志的数据包---》服务端,然后客户端进入SYN_SEND状态,等待服务器的确认。二次握手:服务端发送带有SYN+A......
  • TCP图文详解到底什么是三次握手四次挥手
    为什么会有TCP/IP协议在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别。就好像圣经中上帝打乱了各地人的口音,让他们无法合作一样。计算机使用者意识到,计算机只是单兵作战并不会发挥太大的作用。只有把......
  • 上海泗博HART转ModbusTCP网关HME-635应用案例之组态王和超声波液位计通信
    如今工业现场的应用也逐渐把现场的不同应用协议转换成以太网,以此来提升现场的通信速度和质量。ModbusTCP是工业以太网协议的一种,也是现场应用中最常使用的。本应用案例是基于ModbusTCP的组态王和基于HART的超声波液位计之间数据通讯的具体应用。应用图如下:  上海泗博HART......