首页 > 代码库 > C/C++网络编程中的TCP保活

C/C++网络编程中的TCP保活

原博客:http://blog.csdn.net/weiwangchao_/article/details/7225338

Linux环境下的TCP Keepalive参数设置

  为什么说是系统默认值的呢?因为有这样几个值,我们并没有手动设置,是采用的系统默认值。即,

  1. 多长时间发送一次保活心跳?
  2. 如果没有返回,多长时间再重试发送?
  3. 重试几次为失败?

      如果是Linux操作系统,这三个值分别为

    1. # cat /proc/sys/net/ipv4/tcp_keepalive_time    
    2. 7200    
    3. # cat /proc/sys/net/ipv4/tcp_keepalive_intvl    
    4. 75    
    5. # cat /proc/sys/net/ipv4/tcp_keepalive_probes    
    6. 9  

  这就是说,在Linux系统下,如果对于TCP的socket启用了Keepalive选项,则会在7200秒(即两个小时)没有数据后,发起KEEPALIVE报文。如果没有回应,则会在75秒后再次重试。如果重试9次均失败,则认定连接已经失效。TCP的读取操作,将返回0。

  这对于我们大多数应用来说,前两个时间值都有点太长了。

  我们可以通过重设上面三个值,来使得操作系统上运行的所有启用了Keepalive选项的TCP的socket的行为更改。

  我们也可以只针对我们自己创建的socket,重设这三个值。它们分别对应TCP_KEEPIDLE、TCP_KEEPINTL和TCP_KEEPCNT的选项值,同样可以使用setsockopt进行设置。

技术分享
 1 #include <stdlib.h>   
 2 #include <fcntl.h>    
 3 #include <errno.h>    
 4 #include <sys/socket.h>    
 5 #include <netinet/tcp.h>    
 6 #include <netinet/in.h>    
 7 #include <netdb.h>    
 8 #include <arpa/inet.h>    
 9     
10 int    
11 socket_set_keepalive (int fd)    
12 {    
13   int ret, error, flag, alive, idle, cnt, intv;    
14     
15   /* Set: use keepalive on fd */    
16   alive = 1;    
17   if (setsockopt    
18       (fd, SOL_SOCKET, SO_KEEPALIVE, &alive,    
19        sizeof alive) != 0)    
20     {    
21       log_warn ("Set keepalive error: %s.\n", strerror (errno));    
22       return -1;    
23     }    
24     
25   /* 10秒钟无数据,触发保活机制,发送保活包 */    
26   idle = 10;    
27   if (setsockopt (fd, SOL_TCP, TCP_KEEPIDLE, &idle, sizeof idle) != 0)    
28     {    
29       log_warn ("Set keepalive idle error: %s.\n", strerror (errno));    
30       return -1;    
31     }    
32     
33   /* 如果没有收到回应,则5秒钟后重发保活包 */    
34   intv = 5;    
35   if (setsockopt (fd, SOL_TCP, TCP_KEEPINTVL, &intv, sizeof intv) != 0)    
36     {    
37       log_warn ("Set keepalive intv error: %s.\n", strerror (errno));    
38       return -1;    
39     }    
40     
41   /* 连续3次没收到保活包,视为连接失效 */    
42   cnt = 3;    
43   if (setsockopt (fd, SOL_TCP, TCP_KEEPCNT, &cnt, sizeof cnt) != 0)    
44     {    
45       log_warn ("Set keepalive cnt error: %s.\n", strerror (errno));    
46       return -1;    
47     }    
48     
49   return 0;    
50 }    
c++例子

 

C/C++网络编程中的TCP保活