zoukankan      html  css  js  c++  java
  • 《网络编程实战》笔记 | 12 连接无效:使用Keep-Alive还是应用心跳来检测?

    0 前言

    之所以要进行连接无效的检查,是因为有应用场景需要保持 TCP 连接处于可用状态,如果连接断开,可能需要报错或者重新发起连接。就比如即时通信软件,当与服务器断开连接而不自知,当你想发消息才发现断开连接,可能你追了很久的那个人突然给你发了一条消息,“我有点想你”,过了几分钟就撤回了,你断开连接而不自知,就错过了进一步发展的机会。

    1 TCP Keep-Alive 选项

    Keep-Alive 是 TCP 协议本身有一个保活机制,设定一个保活计时器,当有数据交互时,会重置保活计时器。当连接上一直没有数据,保活时间到,会每个一段时间就发送探测报文,若连续几个探测报文都没有相应,则认为TCP 连接死亡,系统内核将错误信息通知给上层应用程序。
    该机制有三个可定义变量:保活时间、保活时间间隔和保活探测次数,在 Linux 系统中,这些变量分别对应 sysctl 变量:net.ipv4.tcp_keepalive_time、net.ipv4.tcp_keepalive_intvl、 net.ipv4.tcp_keepalve_probes,默认设置是 7200 秒(2小时)、75 秒和 9 次探测。也就是2个小时都没有报文交互,则发送探测报文,探测报文间隔75 秒发送,当9次都没有回复,则判断连接死亡。

    matt@ubuntu:~$ sudo sysctl -a | grep net.ipv4.tcp_keepalive
    [sudo] password for matt:
    net.ipv4.tcp_keepalive_intvl = 75
    net.ipv4.tcp_keepalive_probes = 9
    net.ipv4.tcp_keepalive_time = 7200
    

    因为早起网络带宽资源有限,所以默认的保活机制的频率很低,很多时延敏感系统中,默认的这个时间间隔不可接受,需要重新配置参数,或者在应用层寻找解决方案。

    2 应用层探活

    应用层设计保活程序,可以设计 PING-PONG 的机制,需要保活则发起一个 PING 报文,得到 PONG 回复则重置保活时间,否则探测次数计数,继续发送,达到预设次数,则判定连接无效。
    关键点:
    1. 需要使用定时器,可以使用 I/O 多路复用(select,epoll等都带有超时机制)自身的机制实现;如使用 select 时,成功则返回监听到时间的描述符个数,失败返回-1,超时返回 0 ;

    #define KEEP_ALIVE_PROBETIMES 3 //探测次数
    #define KEEP_ALIVE_INTERVAL   3 //探测间隔
    #define KEEP_ALIVE_TIME      10 //保活时间
    
        struct timeval tv;
        int heartbeats = 0;
        tv.tv_sec = KEEP_ALIVE_TIME;
        tv.tv_usec = 0;
    
        int rc = select(socket_fd + 1, &readmask, NULL, NULL, &tv);
        if(rc<0){
            perror("select failed");
            exit(1);
        }
        if(rc == 0){
            if(++heartbeats >KEEP_ALIVE_PROBETIMES){
                printf("connection dead");
                exit(0);
            }
            printf("sending heartbead #%d
    ", heartbeats);
            ping_message.type = htonl(MSG_PING);
            rc = send(socket_fd,(char *)&ping_message, sizeof(messageObject),0);
            if(rc<0){
                perror("send failed");
                exit(1);
            }
            tv.tv_sec = KEEP_ALIVE_INTERVAL;
            continue;
        }
    
      2. 需要设计一个 PING-PONG 协议。
    
    typedef struct {
     u_int32_t type;
     char data[1024];
    } messageObject;
    #define MSG_PING 1
    #define MSG_PONG 2
    #define MSG_TYPE1 11
    #define MSG_TYPE2 21
    
  • 相关阅读:
    49个128*128像素的天气png图标
    非常漂亮的千千静听皮肤[Warp]出自梦梦的作品
    腾讯的面试题
    什么是函数参数,如何传递函数参数
    我看了这视频,情不自禁的笑了
    WindowBlinds基础使用教程
    晒工资网站
    一个可以搜索word文档,电子表格,PDF,幻灯片的搜索引擎
    网页设计常用png小图标一套
    使用U盘时候的”无法停用通用卷”的解决办法
  • 原文地址:https://www.cnblogs.com/1million/p/14341753.html
Copyright © 2011-2022 走看看