linux下使用TCP存活(keepalive)定时器_keepalive_idletime 头文件-程序员宅基地

技术标签: tcp  variables  Network  linux  服务器  socket  parameters  

2008-05-22 14:34

/*由 hi.baidu.com/zhihui3409 收集整理,转载时请附带 此行*/

 

一、什么是keepalive定时器?[ 1]

在一 个空闲的( idle ) TCP 连接上,没有任 何的数据流,许多 TCP/IP 的初学者都对此感到惊奇。也就是说,如果 TCP 连 接两端没有任何一个进程在向对方发送数据,那么在这两个 TCP 模块之间没有任何的数据交换。你可能 在其它的网络协议中发现有轮询( polling ),但在 TCP 中 它不存在。言外之意就是我们只要启动一个客户端进程,同服务器建立了 TCP 连接,不管你离开几小 时,几天,几星期或是几个月,连接依旧存在。中间的路由器可能崩溃或者重启,电话线可能 go down 或 者 back up ,只要连接两端的主机没有重启,连接依旧保持建立。

这就 可以认为不管是客户端的还是服务器端的应用程序都没有应用程序级( application-level ) 的定时器来探测连接的不活动状态( inactivity ),从而引起任何一个应用程序的终止。 然 而有的时候,服务器需要知道客户端主机是否已崩溃并且关闭,或者崩溃但重启。许多实现提供了存活定时器来完成这个任务。

存活 定时器是一个包含争议的特征。许多人认为,即使需要这个特征,这种对对方的轮询也应该由应用程序来完成,而不是由 TCP 中 实现。此外, 如果两个终端系统之间的某个中间网络上有连接的暂时中断,那么存活选项( option ) 就能够引起两个进程间一个良好连接的终止。例如,如果正好在某个中间路由器崩溃、重启的时候发送存活探测, TCP 就 将会认为客户端主机已经崩溃,但事实并非如此。

存活 ( keepalive )并不是 TCP 规范的 一部分。在 Host Requirements RFC 罗列有不使用它的三个理由:( 1 ) 在短暂的故障期间,它们可能引起一个良好连接( good connection )被释放( dropped ), ( 2 )它们消费了不必要的宽带,( 3 )在以 数据包计费的互联网上它们(额外)花费金钱。然而,在许多的实现中提供了存活定时器。

一些 服务器应用程序可能代表客户端占用资源,它们需要知道客户端主机是否崩溃。存活定时器可以为这些应用程序提供探测服务。 Telnet 服 务器和 Rlogin 服务器的许多版本都默认提供存活选项。

个人 计算机用户使用 TCP/IP 协议通过 Telnet 登 录一台主机,这是能够说明需要使用存活定时器的一个常用例子。如果某个用户在使用结束时只是关掉了电源,而没有注销( log off ),那么他就留下了一个半打开( half-open )的连接。在 图 18.16 ,我们看到如何在一个半打开连接上通过发送数据,得到一个复位( reset ) 返回,但那是在客户端,是由客户端发送的数据。如果客户端消失,留给了服务器端半打开的连接,并且服务器又在等待客户端的数据,那么等待将永远持续下去。 存活特征的目的就是在服务器端检测这种半打开连接。

二、keepalive如何工作?[ 1]

在 此描述中,我们称使用存活选项的那一段为服务器,另一端为客户端。也可以在客户端设置该选项,且没有不允许这样做的理由,但通常设置在服务器。如果连接两 端都需要探测对方是否消失,那么就可以在两端同时设置(比如 NFS )。

若 在一个给定连接上,两小时之内无任何活动,服务器便向客户端发送一个探测段。(我们将在下面的例子中看到探测段的样子。)客户端主机必须是下列四种状态之 一:

 

1) 客户端主机依旧活跃( up )运行,并且从服务器可到达。从客户端 TCP 的 正常响应,服务器知道对方仍然活跃。服务器的 TCP 为接下来的两小时复位存活定时器,如果在这两个 小时到期之前,连接上发生应用程序的通信,则定时器重新为往下的两小时复位,并且接着交换数据。

2) 客户端已经崩溃,或者已经关闭( down ),或者正在重启过程 中。在这两种情况下,它的 TCP 都不会响应。服务器没有收到对其发出探测的响应,并且在 75 秒 之后超时。服务器将总共发送 10 个这样的探测,每个探测 75 秒。 如果没有收到一个响应,它就认为客户端主机已经关闭并终止连接。

 

3) 客户端曾经崩溃,但已经重启。这种情况下,服务器将会收到对其存活探测的响应,但该响应是一个复位,从而引起服务器对连接的终止。

 

4) 客户端主机活跃运行,但从服务器不可到达。这与状态 2 类似,因为 TCP 无 法区别它们两个。它所能表明的仅是未收到对其探测的回复。

服务器不必 担心客户端主机被关闭然后重启的情况(这里指的是操作员执行的正常关闭,而不是主机的崩溃)。当系统被操作员关闭时,所有的应用程序进程(也 就是客户端进程) 都将被终止,客户端 TCP 会在连接上发送一个 FIN 。 收到这个 FIN 后,服务器 TCP 向服务器进 程报告一个文件结束,以允许服务器检测这种状态。

 

在第一种状态下,服务器应用程序 不知道存活探测是否发生。凡事都是由 TCP 层处理的,存活探测对 应用程序透明,直到后面 2 , 3 , 4 三 种状态发生。在这三种状态下,通过服务器的 TCP ,返回给服务器应用程序错误信息。(通常服务器向 网络发出一个读请求,等待客户端的数据。如果存活特征返回一个错误信息,则将该信息作为读操作的返回值返回给服务器。)在状态 2 , 错误信息类似于“连接超时”。状态 3 则为“连接被对方复位”。第四种状态看起来像连接超时,或者根 据是否收到与该连接相关的 ICMP 错误信息,而可能返回其它的错误信息。

三、在Linux中如何使用keepalive ?[2]

Linux has built-in support for keepalive. You need to enable TCP/IP networking in order to use it. You also need procfs support and sysctl support to be able to configure the kernel parameters at runtime.

The procedures involving keepalive use three user-driven variables:

 

tcp_keepalive_time

the interval between the last data packet sent (simple ACKs are not considered data) and the first keepalive probe; after the connection is marked to need keepalive, this counter is not used any further

tcp_keepalive_intvl

the interval between subsequential keepalive probes, regardless of what the connection has exchanged in the meantime

tcp_keepalive_probes

the number of unacknowledged probes to send before considering the connection dead and notifying the application layer

 

Remember that keepalive support, even if configured in the kernel, is not the default behavior in Linux. Programs must request keepalive control for their sockets using the setsockopt interface. There are relatively few programs implementing keepalive, but you can easily add keepalive support for most of them following the instructions.

上面一段话已经说 得很明白,linux内核包含对keepalive的支持。其中使用了三个参数:tcp_keepalive_time(开启keepalive的闲置时 长)tcp_keepalive_intvl(keepalive探测包的发送间隔) 和tcp_keepalive_probes (如果对方不予应答,探测包的发送次数);如何配置这三个参数呢?

There are two ways to configure keepalive parameters inside the kernel via userspace commands:

 

  • procfs interface

  • sysctl interface

 

We mainly discuss how this is accomplished on the procfs interface because it's the most used, recommended and the easiest to understand. The sysctl interface, particularly regarding the sysctl (2) syscall and not the sysctl (8) tool, is only here for the purpose of background knowledge.

The procfs interface

This interface requires both sysctl and procfs to be built into the kernel, and procfs mounted somewhere in the filesystem (usually on /proc , as in the examples below). You can read the values for the actual parameters by "catting" files in /proc/sys/net/ipv4/ directory:

 

# cat /proc/sys/net/ipv4/tcp_keepalive_time

7200
# cat /proc/sys/net/ipv4/tcp_keepalive_intvl

75
# cat /proc/sys/net/ipv4/tcp_keepalive_probes 

9

 

 

The first two parameters are expressed in seconds, and the last is the pure number. This means that the keepalive routines wait for two hours (7200 secs) before sending the first keepalive probe, and then resend it every 75 seconds. If no ACK response is received for nine consecutive times, the connection is marked as broken.

Modifying this value is straightforward: you need to write new values into the files. Suppose you decide to configure the host so that keepalive starts after ten minutes of channel inactivity, and then send probes in intervals of one minute. Because of the high instability of our network trunk and the low value of the interval, suppose you also want to increase the number of probes to 20.

Here's how we would change the settings:

# echo 600 > /proc/sys/net/ipv4/tcp_keepalive_time


# echo 60 > /proc/sys/net/ipv4/tcp_keepalive_intvl


# echo 20 > /proc/sys/net/ipv4/tcp_keepalive_probes



 

To be sure that all succeeds, recheck the files and confirm these new values are showing in place of the old ones.

这样,上面的三个 参数配置完毕。使这些参数重启时保持不变的方法请阅读参考文献[2]。

四、在程序中如何使用keepalive ?[2]-[4]

All you need to enable keepalive for a specific socket is to set the specific socket option on the socket itself. The prototype of the function is as follows:

int setsockopt
 (int s, int level, int optname, const void *optval, socklen_t optlen)

The first parameter is the socket, previously created with the socket (2) ; the second one must be SOL_SOCKET , and the third must be SO_KEEPALIVE . The fourth parameter must be a boolean integer value, indicating that we want to enable the option, while the last is the size of the value passed before.

According to the manpage, 0 is returned upon success, and -1 is returned on error (and errno is properly set).

There are also three other socket options you can set for keepalive when you write your application. They all use the SOL_TCP level instead of SOL_SOCKET , and they override system-wide variables only for the current socket. If you read without writing first, the current system-wide parameters will be returned.

 

TCP_KEEPCNT : overrides tcp_keepalive_probes

TCP_KEEPIDLE : overrides tcp_keepalive_time

TCP_KEEPINTVL : overrides tcp_keepalive_intvl int keepAlive = 1; // 开启keepalive属性

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/codejoker/article/details/5394100

智能推荐

【工具使用系列】关于MATLAB for mac 运行时崩溃故障的解决方法_matlab_crash_dump-程序员宅基地

文章浏览阅读1.1w次。MATLAB 常见问题的解决方案1. MATLAB for mac使用过程中,突然崩溃……_matlab_crash_dump

PTA 5-10 多项式A除以B (2017cccc初赛L2-2)_pta你需要计算两个多项式相除的商q和余r,其中r的阶数必须小于b的阶数-程序员宅基地

文章浏览阅读2.7k次,点赞4次,收藏3次。5-10多项式A除以B(25分)这仍然是一道关于A/B的题,只不过A和B都换成了多项式。你需要计算两个多项式相除的商Q和余R,其中R的阶数必须小于B的阶数。输入格式:输入分两行,每行给出一个非零多项式,先给出A,再给出B。每行的格式如下:N e[1] c[1] ... e[N] c[N]其中N是该多项式非零项的个数,e[i]是第i个非零项的指数,c_pta你需要计算两个多项式相除的商q和余r,其中r的阶数必须小于b的阶数

【Focal Loss】简单理解 及 Pytorch 代码 Focal Loss for Dense Object Detection_focal loss for dense object detection pytorch-程序员宅基地

文章浏览阅读6.9k次,点赞2次,收藏9次。一、首先回顾下“交叉熵loss Cross Entropy Loss” CE(Pi)=-log(Pi)二、一般地说,我们数据集会存在类别不平衡问题,很多人会在loss上对应不同类别设置不同系数 loss就变成了上面的样子三、Focal loss其实就是通过数学公式上的改变,扩大了不平衡因素在loss上的影响..._focal loss for dense object detection pytorch

50个综合资源类导航网站分享_综合导航-程序员宅基地

文章浏览阅读1.1k次。50个综合资源类导航网站分享,你想有的全都有。_综合导航

QDockWidget的关闭事件_qdockwidget关闭触发什么信号-程序员宅基地

文章浏览阅读1.8k次。qt QDockWidget 关闭事件_qdockwidget关闭触发什么信号

04-树5 Root of AVL Tree (25分)_an avl tree is a self-balancing binary search tree-程序员宅基地

文章浏览阅读2k次。An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is_an avl tree is a self-balancing binary search tree…

随便推点

html点击按钮跳转到另一个界面_网页制作:一个简易美观的登录界面-程序员宅基地

文章浏览阅读2.2w次,点赞62次,收藏449次。效果图目录结构:在我们做一个页面之前,要先想好他的一个整体布局,也就是我们这里面的login.html主页面,大致结构如下:接下来,我们先上代码,看一下具体实现方法:login.html<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>..._html table登陆界面带有页面转换

C语言彩色版贪吃蛇——图形界面Easyx的简单使用_c easyx实现登录-程序员宅基地

文章浏览阅读2w次,点赞40次,收藏237次。大一上大概12月份学完了C语言,基本语法与知识已经基本具备,可以用C语言写出基本的贪吃蛇游戏,但是基础C语言的可视化与交互功能实在是太弱了,为了写出有色彩的游戏,需要在网上安装一个Easyx的插件,具体Easyx如何使用参见https://zhuanlan.zhihu.com/p/24826034点击打开链接然后编程软件我用的是VS 2017(因为Dev C++不支持Easyx) VS安装入口_c easyx实现登录

全球公链进展| Shibarium已上线;opBNB测试网PreContract硬分叉;Sui 主网 V1.7.1 版本_shibarium上线-程序员宅基地

文章浏览阅读1.6k次。Sui 主网现已升级至 V1.7.1 版本,此升级包含了多项修复和优化,包括:协议版本提升至 20 版本,在 Sui 框架中新增 Kiosk Extensions API 和一个新的 sui::kiosk_extension 模块,开发者可使用该 API 构建自定义的 Kiosk 应用程序,以扩展 Kiosk 基本功能;以太坊基金会工程师 Parithosh Jayathi 发推称,Dencun-devnet-8 已上线,这是开发者网络的最新迭代版本,旨在允许客户端与最新规范进行互操作性测试。_shibarium上线

idea显示properties文件中文乱码_idea properties 乱码-程序员宅基地

文章浏览阅读1k次。解决idea显示文件中文乱码在项目中通常会遇到如下问题,突然properties文件中文就显示为\u5730等等这样类似的字符。_idea properties 乱码

【嵌入式实验】南航嵌入式实验报告——GPIO实验_南航nuaa嵌入式系统实验报告-程序员宅基地

文章浏览阅读9.2k次,点赞12次,收藏146次。嵌入式系统原理与应用实验报告-GPIO实验文章目录嵌入式系统原理与应用实验报告-GPIO实验一、实验目的1.1 基于GPIO的LED跑马灯实验1.2 基于GPIO的简单人机交互接口实验1.3 基于GPIO的直流电机控制实验二、实验原理(硬件连接及软件流程、简单原理说明)2.1 实验设备2.2 实验硬件连接图2.3 实验简单原理三、实验内容与实验步骤3.1 基于GPIO的LED跑马灯实验3.1.1 实验内容3.1.2 实验步骤3.1.3 完整实验代码3.2 基于GPIO的简单人机交互接口实验3.2.1 实验_南航nuaa嵌入式系统实验报告

vue3中借助 pdfjs-dist 实现pdf文件展示、文本选中功能及使用过程中部分问题处理_vue3对pdf文件操作文件选取-程序员宅基地

文章浏览阅读2.6k次,点赞30次,收藏30次。一、文件预览1、安装 `pdfjs-dist` ,此处指定版本为 `2.16.105`2、`html` 结构内容3、`js` 功能实现:4、可能出现的问题(1) 部分字体出现乱码或浏览器控制台出现警告二、文本选中1、功能实现2、可能出现的问题:(1) 页面文字可选中,但文本不可见(2) 浏览器控制台报错 `Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'dispatch_vue3对pdf文件操作文件选取