Linux内置支持keepalive机制,为了使用它,你须要使能TCP/IP网络,为了可以配置内核在执行时的參数。你还须要procfs和sysctl的支持。

这个过程涉及到keepalive使用的三个用户驱使的变量:

tcp_keepalive_time:表示的是近期一次数据包(简单的不含数据的ACKs包)发送与第一次keepalive探针发送之间的时间间隔;当连接被标记为keepalive之后。这个计数器就不会再使用。

tcp_keepalive_intvl:表示的是并发keepalive探针之间的时间间隔。

tcp_keepalive_probes:在确定连接已经断开而且通知应用层之前所发送的没有得到回复的探针数。

对于这三个參数能够在Linux系统的终端中查看和改动它们的缺省值:

查看三个參数的值:

[root@Server3 ~]# cat /proc/sys/net/ipv4/tcp_keepalive_time
7200
[root@Server3 ~]# cat /proc/sys/net/ipv4/tcp_keepalive_intvl
75
[root@Server3 ~]# cat /proc/sys/net/ipv4/tcp_keepalive_probes
9

通过命令对这三个參数值进行改动(图中将三个參数值分别设为:600、60、20):

[root@Server3 ~]# echo 600 > /proc/sys/net/ipv4/tcp_keepalive_time
[root@Server3 ~]# echo 60 > /proc/sys/net/ipv4/tcp_keepalive_intvl
[root@Server3 ~]# echo 6 > /proc/sys/net/ipv4/tcp_keepalive_probes

这样的方式重置三个參数值,在系统重新启动后三个參数的值又会恢复到默认值,详细怎样让系统永远记住自己设置的值,可參考其它资料,我们如今关系的是怎样在程序中使用keepalive机制并设置这三个參数的值。

在程序中使用keepalive机制

想在程序中使用这样的机制,仅仅须要使用setsockopt()函数。

setsockopt()函数用于随意类型、随意状态套接口的设置选项值。虽然在不同协议层上存在选项,但本函数仅定义了最高的“套接口”层次上的选项。

选项影响套接口的操作,诸如加急数据是否在普通数据流中接收,广播数据能否够从套接口发送等等。

以下为setsockopt()函数的原型:

#include <sys/types.h>
#include <sys/socket.h>
int setsockopt(int sock, int level, int optname, const void *optval, socklen_t optlen);

參数:  

sock:将要被设置或者获取选项的套接字。

level:选项所在的协议层。

optname:须要訪问的选项名。

optval:对于getsockopt()。指向返回选项值的缓冲。对于setsockopt()。指向包括新选项值的缓冲。

optlen:对于getsockopt()。作为入口參数时,选项值的最大长度。作为出口參数时。选项值的实际长度。

对于setsockopt()。现选项的长度。

为了使用函数setsockopt()将某个特定的套接字的keepalive机制打开,參数s是一个socket文件描写叙述符。必需要在这之前使用socket()函数进行创建。參数level必须设置为SOL_SOCKET;第三个參数必须设置为SO_KEEPALIVE。optval參数必须是一个布尔型整型变量,表示想要使能这个选项;最后一个參数表示第四个參数的大小。

程序实现心跳包检測机制

首先要在备份机和源机之间建立一个专门的socket链路来进行心跳检測。

在源机端,在进行数据迁移之前,会建立一个socket来监听备份机的连接。并将这个socket和相应的处理函数放入原软件的io处理列表中。代码例如以下:

int listenfd;
struct sockaddr_in server_sin; /* establish socket */
listenfd=socket(AF_INET,SOCK_STREAM,0);
server_sin.sin_family=AF_INET;
server_sin.sin_addr.s_addr=htonl(INADDR_ANY);
server_sin.sin_port=htons(PORT);
bind(listenfd,(struct sockaddr *)&server_sin,sizeof(server_sin));
/* establish end */ listen(listenfd,1024); qemu_set_fd_handler2(listenfd, NULL, tcpkeepalive_server, NULL,
(void *)(intptr_t)listenfd);

该socket相应的处理函数例如以下:

static void tcpkeepalive_server(void *opaque)
{
int connfd;
struct sockaddr_in client_sin;
socklen_t client_len=sizeof(client_sin);
int listenfd = (intptr_t)opaque; connfd=accept(listenfd,(struct sockaddr *)&client_sin,&client_len);
}

在备份机端,当其開始作为备份机时,会建立socket连接源机的监听端。并设置相应的tcpkeepalive參数。然后将socket和相应的处理函数增加io处理列表。

我们建立的socket是一个心跳检測专用链路。其上不会有数据流动,仅仅有一种情况备份机端会收到数据,那就是源端出现了故障。tcpkeepalive机制会返回一个错误信息,所以捕捉到了这个信息,备份机就会跳转到相应的处理函数,接替源机開始执行。

相应代码例如以下:

int sockfd;
struct sockaddr_in sin; int optval;
socklen_t optlen = sizeof(optval); sockfd=socket(AF_INET,SOCK_STREAM,0);
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=addr.sin_addr.s_addr;
sin.sin_port=htons(PORT); optval = 1;
setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen); optval = 5;
setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, &optval, optlen); optval = 1;
setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE, &optval, optlen); optval = 1;
setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL, &optval, optlen); connect(sockfd,(struct sockaddr *)&sin,sizeof(sin)); qemu_set_fd_handler2(sockfd, NULL, tcpkeepalive_vm_start, NULL,
(void *)(intptr_t)sockfd);

该socket相应的处理函数非常easy,就是让备份机開始执行:

static void tcpkeepalive_vm_start(void *opaque)
{
vm_start();
}

在Linux环境下使用TCP的keepalive机制的更多相关文章

  1. mosquitto在Linux环境下的部署/安装/使用/测试

    mosquitto在Linux环境下的部署 看了有三四天的的源码,(当然没怎么好好看了),突然发现对mosquitto的源码有了一点点感觉,于是在第五天决定在Linux环境下部署mosquitto. ...

  2. Linux环境下发布.net core

    一.安装Linux环境 1. 安装VM虚拟机和操作系统 VM虚拟工具安装的过程详见:http://blog.csdn.net/stpeace/article/details/78598333.直接按照 ...

  3. linux 环境下部署 Asp.Net Core 项目 访问 oralce 数据库

    1.ASP.NET Core 是一个跨平台的高性能开源框架,可以部署到Linux上,那项目部署在Linux上有哪些好处呢? 1.linux硬件需求小,大部分版本免费,成本低. 2.linux的用户管理 ...

  4. 关于ARP攻击的原理以及在Kali Linux环境下的实现

    关于ARP攻击的原理以及在Kali Linux环境下的实现 全文摘要 本文讲述内容分为两部分,前半部分讲述ARP协议及ARP攻击原理,后半部分讲述在Kali Linux环境下如何实现ARP攻击以及AR ...

  5. [原]对Linux环境下任务调度一点认识

    我一直以来有一个误解,那就是在终端运行某个程序时,按下Ctrl + D时我误以为就是杀死了这个进程,今天才知道原来不是.比如我利用libevent在Linux环境下写了一个网络监听程序,当启动程序之后 ...

  6. 【转载】linux环境下tcpdump源代码分析

    linux环境下tcpdump源代码分析 原文时间 2013-10-11 13:13:02  CSDN博客 原文链接  http://blog.csdn.net/han_dawei/article/d ...

  7. linux环境下tcpdump源代码分析

    Linux 环境下tcpdump 源代码分析 韩大卫@吉林师范大学 tcpdump.c 是tcpdump 工具的main.c, 本文旨对tcpdump的框架有简单了解,只展示linux平台使用的一部分 ...

  8. 由一个简单需求到Linux环境下的syslog、unix domain socket

    本文记录了因为一个简单的日志需求,继而对linux环境下syslog.rsyslog.unix domain socket的学习.本文关注使用层面,并不涉及rsyslog的实现原理,感兴趣的读者可以参 ...

  9. Memcached在Linux环境下的使用详解

    一.引言             写有关NoSQL数据库有关的文章已经有一段时间了,可以高兴的说,Redis暂时就算写完了,从安装到数据类型,在到集群,几乎都写到了.如果以后有了心得,再补充吧.然后就 ...

随机推荐

  1. 关于mysql服务突然运行不了的问题-“本地计算机上的mysql服务启动后停止,某些...”

    1.将mysql数据库的安装目录bin文件路径添加到环境的path中,为了让cmd可以直接输入下面的相关命令,不然cd到mysql的bin下也可以 2.cmd输入mysqld --initialize ...

  2. 剑指Offer(Python)

    014-链表中倒数第k个结点 用快慢指针:p2比p1先走到k:间隔了k-1)步,然后再一起走,当p2为最后一个时,p1就为倒数第k个数 class ListNode: def __init__(sel ...

  3. Ztree 多选,显示勾选的路径

    项目要求,需要向后台传递已经勾选的路径,如 l1-a, l1-l3-c,l1-l3-d;(如果是全选状态则只传递全选状态的路径,不传子节点). 具体可以参考jQ  Ztree 的 v3.5 版本 Me ...

  4. JS数组专题1️⃣ ➖ 数组扁平化

    一.什么是数组扁平化 扁平化,顾名思义就是减少复杂性装饰,使其事物本身更简洁.简单,突出主题. 数组扁平化,对着上面意思套也知道了,就是将一个复杂的嵌套多层的数组,一层一层的转化为层级较少或者只有一层 ...

  5. 通过洛谷P2639看01背包

    题目描述 Bessie像她的诸多姊妹一样,因为从Farmer John的草地吃了太多美味的草而长出了太多的赘肉.所以FJ将她置于一个及其严格的节食计划之中.她每天不能吃多过H ( <= H &l ...

  6. mysql 数据库 show命令

    MySQL中有很多的基本命令,show命令也是其中之一,在很多使用者中对show命令的使用还容易产生混淆,本文汇集了show命令的众多用法. 1. show tables或show tables fr ...

  7. 蓝牙bluez学习(1) Stack Architecture

    Bluez支持的features Core Specification 4.2 (GAP, L2CAP, RFCOMM, SDP, GATT) Classic Bluetooth (BR/EDR) B ...

  8. 树莓派 - MQTT

    安装mosquitto 下载源代码包 wget http://mosquitto.org/files/source/mosquitto-1.5.tar.gz 解压 tar zxfv mosquitto ...

  9. 分享一款非常好用的Fatkun图片批量下载工具

    Fatkun图片批量下载 相信大家一定遇到过有着大量精美图片的网页,譬如美女照片.各种壁纸.设计素材.甚至是1024套图等等,但常常几十上百张的图要一张张手工去点击下载实在能让人抓狂!小编的工作中也常 ...

  10. Python的Turtle绘制纳兹咩的娘口三三

    今天看完夏目友人帐的大电影,哭成了泪猴~ 所以我打算用Python画一只娘口三三陪伴在我身边 不过.. 画的太丑,还没上色..,你们可以完善一下~ 代码放在这里了 import turtle as t ...