tcp keepalive for unix

1959阅读 0评论2009-10-26 wqfhenanxc_cu
分类:LINUX

   一个TCP套接口创建后默认是没有开启keepalive选项的,要使用setsockopt()函数来开启。
 
   keepalive选项开启后,tcp_keepalive_time、tcp_keepalive_interval、tcp_keepalive_probes三个值都采用系统的默认值,使用getsockopt()函数可以查看这些值。改变这些值有两种方法:一是改变系统默认值,这样的话创建的socket默认都采用该值,二是对socket使用setsockopt()函数改变某个socket的这三个值。

   查看和改变系统默认值的方法:
   1.
  # 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

  # 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
   2.
  # sysctl \
  > net.ipv4.tcp_keepalive_time \
  > net.ipv4.tcp_keepalive_intvl \
  > net.ipv4.tcp_keepalive_probes
  net.ipv4.tcp_keepalive_time = 7200
  net.ipv4.tcp_keepalive_intvl = 75
  net.ipv4.tcp_keepalive_probes = 9

  # sysctl -w \
  > net.ipv4.tcp_keepalive_time=600 \
  > net.ipv4.tcp_keepalive_intvl=60 \
  > net.ipv4.tcp_keepalive_probes=20
  net.ipv4.tcp_keepalive_time = 600
  net.ipv4.tcp_keepalive_intvl = 60
  net.ipv4.tcp_keepalive_probes = 20

  使用函数查看和改变某个socket的keepalive相关值:
//tcp_keepalive.c
#include
#include
#include
#include
#include
#include
#include

//#define EXIT_FAILURE -1
//#define EXIT_SUCCESS 0
#define perror printf


int main()
{
   int s,t;
   int optval;
   int tcp_keepalive_time;
   int tcp_keepalive_interval;
   int tcp_keepalive_probes;

   socklen_t optlen = sizeof(optval);

   /* Create the socket */
   if((s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
      perror("socket()");
      exit(EXIT_FAILURE);
   }


   /* Check the status for the keepalive option */
   if(getsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0) {
      perror("getsockopt()");
      close(s);
      exit(EXIT_FAILURE);
   }
   printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF"));
   /* Check keepalive parameters */
   getsockopt(s,SOL_TCP,TCP_KEEPIDLE,&tcp_keepalive_time,&optlen);
   getsockopt(s,SOL_TCP,TCP_KEEPINTVL,&tcp_keepalive_interval,&optlen);
   getsockopt(s,SOL_TCP,TCP_KEEPCNT,&tcp_keepalive_probes,&optlen);
   printf("tcp_keepalive_time: %d,tcp_keepalive_interval: %d,tcp_keepalive_probes: %d\n",
           tcp_keepalive_time,tcp_keepalive_interval,tcp_keepalive_probes);


   /* Set the option active */
   optval = 1;
   optlen = sizeof(optval);
   if(setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
      perror("setsockopt()");
      close(s);
      exit(EXIT_FAILURE);
   }
   printf("SO_KEEPALIVE set on socket\n");
   /* Check the status again */
   if(getsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0) {
      perror("getsockopt()");
      close(s);
      exit(EXIT_FAILURE);
   }
   printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF"));
   /* Check keepalive parameters */
   getsockopt(s,SOL_TCP,TCP_KEEPIDLE,&tcp_keepalive_time,&optlen);
   getsockopt(s,SOL_TCP,TCP_KEEPINTVL,&tcp_keepalive_interval,&optlen);
   getsockopt(s,SOL_TCP,TCP_KEEPCNT,&tcp_keepalive_probes,&optlen);
   printf("tcp_keepalive_time: %d,tcp_keepalive_interval: %d,tcp_keepalive_probes: %d\n",
           tcp_keepalive_time,tcp_keepalive_interval,tcp_keepalive_probes);


   /* Set keepalive parameters */
   tcp_keepalive_time=180;
   tcp_keepalive_interval=60;
   tcp_keepalive_probes=20;
   optlen=sizeof(tcp_keepalive_time);
   setsockopt(s,SOL_TCP,TCP_KEEPIDLE,&tcp_keepalive_time,optlen);
   optlen=sizeof(tcp_keepalive_interval);
   setsockopt(s,SOL_TCP,TCP_KEEPINTVL,&tcp_keepalive_interval,optlen);
   optlen=sizeof(tcp_keepalive_probes);
   setsockopt(s,SOL_TCP,TCP_KEEPCNT,&tcp_keepalive_probes,optlen);
   /* Check keepalive parameters */
   getsockopt(s,SOL_TCP,TCP_KEEPIDLE,&tcp_keepalive_time,&optlen);
   getsockopt(s,SOL_TCP,TCP_KEEPINTVL,&tcp_keepalive_interval,&optlen);
   getsockopt(s,SOL_TCP,TCP_KEEPCNT,&tcp_keepalive_probes,&optlen);
   printf("tcp_keepalive_time: %d,tcp_keepalive_interval: %d,tcp_keepalive_probes: %d\n",
           tcp_keepalive_time,tcp_keepalive_interval,tcp_keepalive_probes);


   /* Create another socket */
   if((t = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
      perror("socket()");
      exit(EXIT_FAILURE);
   }
   /* Check the status again */
   if(getsockopt(t, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0) {
      perror("getsockopt()");
      close(s);
      exit(EXIT_FAILURE);
   }
   printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF"));
   /* Check keepalive parameters */
   getsockopt(t,SOL_TCP,TCP_KEEPIDLE,&tcp_keepalive_time,&optlen);
   getsockopt(t,SOL_TCP,TCP_KEEPINTVL,&tcp_keepalive_interval,&optlen);
   getsockopt(t,SOL_TCP,TCP_KEEPCNT,&tcp_keepalive_probes,&optlen);
   printf("tcp_keepalive_time: %d,tcp_keepalive_interval: %d,tcp_keepalive_probes: %d\n",
           tcp_keepalive_time,tcp_keepalive_interval,tcp_keepalive_probes);

   close(s);
   close(t);

   exit(EXIT_SUCCESS);
}
上一篇:tcp/ip illustrated volume 2 chapter2
下一篇:服务器和客户端编写要考虑的问题