TCP_KEEPALIVE选项只是一个开关,Linux中默认的Keepalive的选项如下:

$sudo sysctl -a | grep keepalive
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75

上文中的keepalive选项表示如果一个连接上7200s后没有任何数据发送,则设置了这个选项的本端向对端发送keepalive保活报文,它会有如下三种结果:

  • 对端回复ACK。则本端TCP认为该连接依然存活。继续等7200s后再发送keepalive报文。
  • 对端回复RESET。说明对端进程已经重启,本端的应用程序应该关闭该连接。
  • 没有对端的任何回复。则本端做重试,如果重试9次(前后重试间隔为75秒)仍然不可达,则向应用程序返回错误信息,ETIMEOUT(无任何应答)或EHOST

如果应用程序向改变keepalive的默认行为,该怎么办呢?答案就是利用 TCP_KEEPIDLE、TCP_KEEPINTVL、TCP_KEEPCNT这几个TCP选项,首先看看如何使用:

int setKeepAlive(int fd, int interval)
{
int val = 1; if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1) {
printf("setsockopt SO_KEEPALIVE: %s", strerror(errno));
return -1;
} /* Send first probe after `interval' seconds. */
val = interval;
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0) {
printf("setsockopt TCP_KEEPIDLE: %s\n", strerror(errno));
return -1;
} /* Send next probes after the specified interval. Note that we set the
* delay as interval / 3, as we send three probes before detecting
* an error (see the next setsockopt call). */
val = interval/3;
if (val == 0) val = 1;
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < 0) {
printf("setsockopt TCP_KEEPINTVL: %s\n", strerror(errno));
return -1;
} /* Consider the socket in error state after three we send three ACK
* probes without getting a reply. */
val = 3;
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) {
printf("setsockopt TCP_KEEPCNT: %s\n", strerror(errno));
return -1;
} return 0;
}
  • TCP_KEEPDILE 设置连接上如果没有数据发送的话,多久后发送keepalive探测分组,单位是秒
  • TCP_KEEPINTVL 前后两次探测之间的时间间隔,单位是秒
  • TCP_KEEPCNT 关闭一个非活跃连接之前的最大重试次数

用tcpdump抓包就可以看到设置了上面选项的那端的详细行为。

Date: 2015-07-17T19:45+0800

Author: Cobbliu

Org version 7.9.3f with Emacs version 24

最新文章

  1. 事件DOMContentLoaded和load的区别
  2. hdu2874 LCA在线算法
  3. mysql-批量修改表字段中的某一部分内容
  4. express教程
  5. Use a cache
  6. Android Drawable
  7. 破解 Rith&#39;s CrackMe #1(对比IDA查看动态分析中的MFC函数名)
  8. HDU-3872 Dragon Ball 线段树+DP
  9. 标准I/O库之二进制I/O
  10. Xamarin.Forms DataGrid
  11. HDU 4268 Alice and Bob set用法
  12. java的几个版本以及jre,jdk等概念——【转载】JDK、Java SE、Java EE、Java ME我该选
  13. 【学习笔记】锋利的jQuery(一)选择器
  14. Java的static关键字
  15. [转]Oracle 创建 DBLink 的方法
  16. vue2.0插件--loading
  17. Centos7 安装nginx1.14
  18. centos7下/etc/rc.local文件里配置的开机启动项不执行的解决办法
  19. 将 tomcat 安装成 windows 服务
  20. 高并发第八弹:J.U.C起航(java.util.concurrent)

热门文章

  1. [leetcode]Jump Game @ Python
  2. 遮罩层中的相对定位与绝对定位(Ajax)
  3. Wildcard Matching leetcode java
  4. Javassist 字节码 语法 MD
  5. 混合开发 Hybird Cordova PhoneGap web 跨平台 MD
  6. Linux下简单线程池的实现
  7. Spring(十九):Spring AOP(三):切面的优先级、重复使用切入点表达式
  8. 四轴自适应控制算法的一些尝试开源我的山猫飞控和梯度在线辨识自适应等算法&mdash;(转)
  9. 转:在centos安装与启动mysql
  10. 很有用的mobile web application远程调试工具 weinre