SO_KEEPALIVE选项

SO_KEEPALIVE选项 

  对于面向连接的TCP socket,在实际应用中通常都要检测对端是否处于连接中,连接端口分两种情况:
  1、连接正常关闭,调用close() shutdown()连接优雅关闭,send与recv立马返回错误,select返回SOCK_ERR;
  2、连接的对端异常关闭,比如网络断掉,突然断电.
对于第二种情况,判断连接是否断开的方法有一下几种:
1、自己编写心跳包程序,简单的说就是自己的程序加入一条线程,定时向对端发送数据包,查看是否有ACK,根据ACK的返回情况来管理连接。此方法比较通用,一般使用业务层心跳处理,灵活可控,但改变了现有的协议;
2、使用TCP的keepalive机制,UNIX网络编程不推荐使用SO_KEEPALIVE来做心跳检测(为什么??)。
keepalive原理:TCP内嵌有心跳包,以服务端为例,当server检测到超过一定时间(/proc/sys/net/ipv4/tcp_keepalive_time 7200 即2小时)没有数据传输,那么会向client端发送一个keepalive packet,此时client端有三种反应:
1、client端连接正常,返回一个ACK.server端收到ACK后重置计时器,在2小时后在发送探测.如果2小时内连接上有数据传输,那么在该时间的基础上向后推延2小时发送探测包;
2、客户端异常关闭,或网络断开。client无响应,server收不到ACK,在一定时间(/proc/sys/net/ipv4/tcp_keepalive_intvl 75 即75秒)后重发keepalive packet, 并且重发一定次数(/proc/sys/net/ipv4/tcp_keepalive_probes 9 即9次);
3、客户端曾经崩溃,但已经重启.server收到的探测响应是一个复位,server端终止连接。

如果我们不能接受如此之长的等待时间,从TCP-Keepalive-HOWTO上可以知道一共有两种方式可以设置,一种是修改内核关于网络方面的 配置参数,另外一种就是SOL_TCP字段的TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT三个选项。

1) The tcp_keepidle parameter specifies the interval of inactivity that causes TCP to generate a KEEPALIVE transmission for an application that requests them. tcp_keepidle defaults to 14400 (two hours).

/*开始首次KeepAlive探测前的TCP空闭时间 */

2) The tcp_keepintvl parameter specifies the interval between the nine retries that are attempted if a KEEPALIVE transmission is not acknowledged. tcp_keepintvl defaults to 150 (75 seconds).
    /* 两次KeepAlive探测间的时间间隔  */

3) The tcp_keepcnt option specifies the maximum number of keepalive probes to be sent. The value of TCP_KEEPCNT is an integer value between 1 and n, where n is the value of the systemwide tcp_keepcnt parameter.

/* 判定断开前的KeepAlive探测次数

int                 keepIdle = 1000;

int                 keepInterval = 10;

int                 keepCount = 10;

Setsockopt(listenfd, SOL_TCP, TCP_KEEPIDLE, (void *)&keepIdle, sizeof(keepIdle));

Setsockopt(listenfd, SOL_TCP,TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));

Setsockopt(listenfd,SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));

Remember that keepalive is not program?related, but socket?related, so if you have multiple sockets, you can handle keepalive for each of them separately.

参考:

1、http://blog.csdn.net/callinglove/article/details/38380673

2、http://blog.chinaunix.net/uid-26575352-id-3483808.html

时间: 2024-10-13 21:51:18

SO_KEEPALIVE选项的相关文章

socket选项总结(setsocketopt)

功能描述:        获取或者设置与某个套接字关联的选 项.选项可能存在于多层协议中,它们总会出现在最上面的套接字层.当操作套接字选项时,选项位于的层和选项的名称必须给出.为了操作套接字层的选项,应该 将层的值指定为SOL_SOCKET.为了操作其它层的选项,控制选项的合适协议号必须给出.例如,为了表示一个选项由TCP协议解析,层应该设定为协议 号TCP. 用法:#include #include int getsockopt(int sock, int level, int optname

几个重要的TCP/IP选项解析(Java Socket)

阅读目录 1. TCP_NODELAY 2.  SO_REUSEADDR 3.  SO_LINGER 4.  SO_TIMEOUT 5.  SO_SNDBUF 6.  SO_RCVBUF 7.  SO_KEEPALIVE 8.  SO_OOBINLINE 参考: Socket选择可以指定Socket类发送和接受数据的方式.在JDK1.4中共有8个Socket选择可以设置.这8个选项都定义在java.net.SocketOptions接口中.定义如下: ? 1 public final stati

UNIX网络编程——套接字选项(心跳检测、绑定地址复用)(转)

/* 设置套接字选项周期性消息检测连通性 心跳包. 心博.主要用于长连接. * 参数:套接字, 1或0开启, 首次间隔时间, 两次间隔时间, 断开次数 */ void setKeepAlive( int iSockfd , int iSockAttrOn, socklen_t iIdleTime , socklen_t iInterval , socklen_t iCount ){ setsockopt( iSockfd , SOL_SOCKET , SO_KEEPALIVE , (const

redis 的安装使用 数据类型 以及操作指令 一

安装 redis 到 /usr/目录下 我这里安装的是redis-3.2.9.tar.gz tar zxvf  redis-3.2.9.tar.gz  -C  /usr 然后进行 执行编译命令 make   执行安装  make install 进入redis目录   ll查看所有文件 将 redis.conf文件 移动到usr/local/redis/etc目录下 再进入redis/src 目录 将以下文件移动到 usr/local/redis/bin目录下  方便以后管理 此时进入 usr/

MQTT与Mosquitto服务器搭建以及Android推送(一)MQTT简介

文章钢要: 对MQTT协议有一定认识 对MQTT运行原理有一定了解 一.什么是MQTT MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议. 国内很多企业都广泛使用MQTT作为Android手机客户端与服务器端推送消息的协议.其中Sohu,Cmstop手机客户端中均有使用到MQTT作为消息推送消息. MQTT由于开放源代码,耗电量小等特点,将会在移动消息推送领域会有更多的贡献,在物联网领域,传感器与服务器的通信,信息

Socket笔记

在客户/服务器通信模式中, 客户端需要主动创建与服务器连接的 Socket(套接字), 服务器端收到了客户端的连接请求, 也会创建与客户连接的 Socket. Socket可看做是通信连接两端的收发器, 服务器与客户端都通过 Socket 来收发数据. 这篇文章首先介绍Socket类的各个构造方法, 以及成员方法的用法, 接着介绍 Socket的一些选项的作用, 这些选项可控制客户建立与服务器的连接, 以及接收和发送数据的行为. 一. 构造Socket Socket的构造方法有以下几种重载形式:

TCP连接建立系列 — 客户端接收SYNACK和发送ACK

主要内容:客户端接收SYNACK.发送ACK,完成连接的建立. 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd 接收入口 tcp_v4_rcv |--> tcp_v4_do_rcv |-> tcp_rcv_state_process |-> tcp_rcv_synsent_state_process 1. 状态为ESTABLISHED时,用tcp_rcv_established()接收处理. 2. 状态为LISTEN时,说明这个sock处于监

redis源码学习(客户端)

大概介绍 redis 客户端设计主要是存储客户的链接,请求,请求解析的命令,执行结果.先看server的结构和client的结构,server里面有多个client,相当于一个服务端可以连多个客户端,服务端根据事件触发模式依次处理客户端的请求. server结构 struct redisServer { /* General */ // 配置文件的绝对路径 char *configfile; /* Absolute config file path, or NULL */ // serverCr

java Socket用法详解(转)

在客户/服务器通信模式中, 客户端需要主动创建与服务器连接的 Socket(套接字), 服务器端收到了客户端的连接请求, 也会创建与客户连接的 Socket. Socket可看做是通信连接两端的收发器, 服务器与客户端都通过 Socket 来收发数据. 这篇文章首先介绍Socket类的各个构造方法, 以及成员方法的用法, 接着介绍 Socket的一些选项的作用, 这些选项可控制客户建立与服务器的连接, 以及接收和发送数据的行为. 一. 构造Socket Socket的构造方法有以下几种重载形式: