Chinaunix首页 | 论坛 | 博客
  • 博客访问: 96898
  • 博文数量: 31
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 380
  • 用 户 组: 普通用户
  • 注册时间: 2014-02-24 22:04
文章分类

全部博文(31)

文章存档

2014年(31)

我的朋友

分类: C/C++

2014-08-04 11:06:11



main
    |-----......
    |-----socketServer
    |-----tcpsetserveropt
    |-----daemon_init
    |-----......

tcpsetseveropt函数在main函数中被调用的代码:

点击(此处)折叠或打开

  1. //设定socket的选项
  2.     if ((result=tcpsetserveropt(sock, g_fdfs_network_timeout)) != 0)
  3.     {
  4.         log_destroy();
  5.         return result;
  6.     }

tcpsetserveropt函数代码:

点击(此处)折叠或打开

  1. //设定socket的选项
  2. int tcpsetserveropt(int fd, const int timeout)
  3. {
  4.     int flags;
  5.     int result;

  6.     struct linger linger;//表示执行close socket后,socket还能存活多久
  7.     struct timeval waittime;

  8.     linger.l_onoff = 1;//开启
  9.     linger.l_linger = timeout * 100;
  10.     if (setsockopt(fd, SOL_SOCKET, SO_LINGER, \//
  11.                 &linger, (socklen_t)sizeof(struct linger)) < 0)
  12.     {
  13.         logError("file: "__FILE__", line: %d, " \
  14.             "setsockopt failed, errno: %d, error info: %s", \
  15.             __LINE__, errno, STRERROR(errno));
  16.         return errno != 0 ? errno : ENOMEM;
  17.     }

  18.     waittime.tv_sec = timeout;
  19.     waittime.tv_usec = 0;

  20.     if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO,//SO_SNDTIMEO,发送的超时时间
  21.                &waittime, (socklen_t)sizeof(struct timeval)) < 0)
  22.     {
  23.         logWarning("file: "__FILE__", line: %d, " \
  24.             "setsockopt failed, errno: %d, error info: %s", \
  25.             __LINE__, errno, STRERROR(errno));
  26.     }

  27.     if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO,//SO_RCVTIMEO,接受的超时时间
  28.                &waittime, (socklen_t)sizeof(struct timeval)) < 0)
  29.     {
  30.         logWarning("file: "__FILE__", line: %d, " \
  31.             "setsockopt failed, errno: %d, error info: %s", \
  32.             __LINE__, errno, STRERROR(errno));
  33.     }

  34.     flags = 1;
  35.     if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, \//TCP_NODELAY:禁止Nagle算法,提高性能
  36.         (char *)&flags, sizeof(flags)) < 0)
  37.     {
  38.         logError("file: "__FILE__", line: %d, " \
  39.             "setsockopt failed, errno: %d, error info: %s", \
  40.             __LINE__, errno, STRERROR(errno));
  41.         return errno != 0 ? errno : EINVAL;
  42.     }

  43.     if ((result=tcpsetkeepalive(fd, 2 * timeout + 1)) != 0)
  44.     {
  45.         return result;
  46.     }

  47.     return 0;
  48. }

tcpsetserveropt函数执行步骤:
(1) 设定SO_LINGER
(2) 设定SO_SNDTIMEO
(3) 设定SO_RCVTIMEO
(4) 设定TCP_NODELAY
(5) 调用tcpsetkeepalive函数,设定keep alive时间


tcpsetkeepalive函数代码:

点击(此处)折叠或打开

  1. int tcpsetkeepalive(int fd, const int idleSeconds)
  2. {
  3.     int keepAlive;

  4. #ifdef OS_LINUX
  5.     int keepIdle;
  6.     int keepInterval;
  7.     int keepCount;
  8. #endif

  9.     keepAlive = 1;
  10.     if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, \ //启用周期性的keep-alive消息
  11.         (char *)&keepAlive, sizeof(keepAlive)) < 0)
  12.     {
  13.         logError("file: "__FILE__", line: %d, " \
  14.             "setsockopt failed, errno: %d, error info: %s", \
  15.             __LINE__, errno, STRERROR(errno));
  16.         return errno != 0 ? errno : EINVAL;
  17.     }

  18. #ifdef OS_LINUX
  19.     keepIdle = idleSeconds;//IPPROTO_TCP可代替SOL_TCP,设置在建立连接后多长时间开始keepalive第一个探测针的发送
  20.     if (setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, (char *)&keepIdle, \
  21.         sizeof(keepIdle)) < 0)
  22.     {
  23.         logError("file: "__FILE__", line: %d, " \
  24.             "setsockopt failed, errno: %d, error info: %s", \
  25.             __LINE__, errno, STRERROR(errno));
  26.         return errno != 0 ? errno : EINVAL;
  27.     }

  28.     keepInterval = 10;//设置keep-alive消息发送的时间间隔 10s
  29.     if (setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, (char *)&keepInterval, \
  30.         sizeof(keepInterval)) < 0)
  31.     {
  32.         logError("file: "__FILE__", line: %d, " \
  33.             "setsockopt failed, errno: %d, error info: %s", \
  34.             __LINE__, errno, STRERROR(errno));
  35.         return errno != 0 ? errno : EINVAL;
  36.     }

  37.     keepCount = 3;//设置这种探测帧应该发多少次,如果发了这么多次探测针后仍然没有收到对方的确认回应则认为对方的连接断开。
  38.     if (setsockopt(fd, SOL_TCP, TCP_KEEPCNT, (char *)&keepCount, \
  39.         sizeof(keepCount)) < 0)
  40.     {
  41.         logError("file: "__FILE__", line: %d, " \
  42.             "setsockopt failed, errno: %d, error info: %s", \
  43.             __LINE__, errno, STRERROR(errno));
  44.         return errno != 0 ? errno : EINVAL;
  45.     }
  46. #endif

  47.     return 0;
  48. }
tcpsetkeepalive函数执行步骤:
(1) 设定SO_KEEPALIVE

(2) 设定TCP_KEEPIDLE
(3) 设定TCP_KEEPINTVL
(4) 设定TCP_KEEPCNT
(5) 设定TCP_NODELAY











阅读(859) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~