zoukankan      html  css  js  c++  java
  • 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 char*)&iSockAttrOn , sizeof(iSockAttrOn) );
        setsockopt( iSockfd , SOL_TCP , TCP_KEEPIDLE , (const char*)&iIdleTime , sizeof(iIdleTime) );
        setsockopt( iSockfd , SOL_TCP , TCP_KEEPINTVL , (const char*)&iInterval,sizeof(iInterval) );
        setsockopt( iSockfd , SOL_TCP , TCP_KEEPCNT , (const char*)&iCount,sizeof(iCount) );
    }
    /* 绑定地址复用. 主要用于TCP Server端 */
    setsockopt(iSockfd, SOL_SOCKET, SO_REUSEADDR, &iSockAttrOn,sizeof(iSockAttrOn) );

        SO_KEEPALIVE 保持连接检测对方主机是否崩溃,避免(服务器)永远阻塞于TCP连接的输入。设置该选项后,如果2小时内在此套接口的任一方向都没有数据交换(即服务器没有发送数据或者接收数据,TCP就自动给对方发一个保持存活探测分节(keepalive probe)。这是一个对方必须响应的TCP分节.它会导致以下三种情况:

    • 对方接收一切正常:以期望的ACK响应。
    • 2小时后,TCP将发出另一个探测分节。对方已崩溃且已重新启动:以RST响应。套接口的待处理错误被置为ECONNRESET(recv返回0,errno为ECONNRESET),套接字本身则被关闭。
    • 对方无任何响应:源自berkeley的TCP发送另外8个探测分节,相隔75秒一个,试图得到一个响应。在发出第一个探测分节11分钟15秒(9*75s)后若仍无响应就放弃。套接口的待处理错误被置为ETIMEOUT,套接口本身则被关闭。如ICMP错误是“host unreachable(主机不可达)”,说明对方主机并没有崩溃,但是不可达,这种情况下待处理错误被置为EHOSTUNREACH。


            如果我们不能接受如此之长的等待时间,从TCP-Keepalive-HOWTO上可以知道一共有两种方式可以设置。

    • 修改内核关于网络方面的配置参数

    echo 30 > /proc/sys/net/ipv4/tcp_keepalive_time
    echo 10 > /proc/sys/net/ipv4/tcp_keepalive_intvl
    echo 3 > /proc/sys/net/ipv4/tcp_keepalive_probes

    • 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.


    我们需要注意的TCP-Keepalive-HOWTO上这段话:

    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.

    这些属性是sockt继承的,即listen的套接字设置该属性后,后面建立连接后的accept 套接字同样继承该属性(心跳属性)。

        如果心搏函数要维护客户端的存活,即服务器必须每隔一段时间必须向客户段发送一定的数据,那么使用SO_KEEPALIVE是有很大的不足的。因为SO_KEEPALIVE选项指"此套接口的任一方向都没有数据交换"。在Linux 2.6系列上,上面话的理解是只要打开SO_KEEPALIVE选项的套接口端检测到数据发送或者数据接收就认为是数据交换。即在非正常断开的情况下(服务器没有收到“FIN”或者“RST”包),上层程序还是可以正常发送包到缓冲区的,而客户端已经异常断开,导致TCP会自动进行重传,重传包的优先级高于keepalive包,那就意味着keepalive总是不能发送出去,这时我们并不知道该连接已经出错而中断,在较长时间的重传失败之后,再发keepalive之后我们才知道客户端异常退出。


         阅读此博客时,可以参考后面的博客<<UNIX网络编程——客户/服务器心搏函数>>和<<UNIX网络编程——socket的keep-alive>>。

  • 相关阅读:
    HDU4628+状态压缩DP
    Javascript 去掉字符串前后空格的五种方法
    Javascript 数组之判断取值和数组取值
    ASP.NET MVC 出现错误 “The view 'XXX' or its master was not found or no view engine support”
    ASP.NET MVC 页面调整并传递参数
    ASP.NET MV3 部署网站 报"Could not load file or assembly ' System.Web.Helpers “ 错的解决方法
    ASP.NET MVC 控制器向View传值的三种方法
    CSharp 如何通过拼接XML调用存储过程来查询数据
    SQLServer : EXEC和sp_executesql的区别
    关于SQLServer2005的学习笔记—异常捕获及处理
  • 原文地址:https://www.cnblogs.com/wangfengju/p/6172578.html
Copyright © 2011-2022 走看看