zoukankan      html  css  js  c++  java
  • linux下的tcp连接超时

    最近需要写一个linux下的通信程序, 通信模块用的是Qt的QTcpSocket.

    最后程序需要增加一个断网检测, 在windows下调试没问题, 拔网线, 断网口都能马上检测到, 但到了部署到linux下就需要等10多分钟才能得到断网的信号.

    调试+google后, 定位问题应该不是Qt的问题, 而是windows和linux下对tcp超时的设置不同导致的, 也找到一些解决方案, 大致可以归纳为两类:

    1. 直接修改系统参数的(链接)
    echo "6" > /proc/sys/net/ipv4/tcp_keepalive_time
    echo "1" > /proc/sys/net/ipv4/tcp_keepalive_intvl
    echo "10" > /proc/sys/net/ipv4/tcp_keepalive_probes
    echo "3" > /proc/sys/net/ipv4/tcp_retries2
    
    1. 在程序里修改参数的 (链接)
    int enableKeepAlive = 1;
    int fd = socket->socketDescriptor();
    setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &enableKeepAlive, sizeof(enableKeepAlive));
    int maxIdle = 10;
    setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &maxIdle, sizeof(maxIdle));
    int count = 3; // send up to 3 keepalive packets out, then disconnect if no response
    setsockopt(fd, SOL_TCP, TCP_KEEPCNT, &count, sizeof(count));
    int interval = 2; // send a keepalive packet out every 2 seconds (after the 5 second idle period)
    setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &interval, sizeof(interval));
    

    一开始不想直接修改系统参数, 就先采用的方案2, 但各种调试发现函数调用都是成功的, 但就是断网的检测还是会10分钟以上超时, 所以实在没辙就试着调了下系统参数.

    调完发现马上就可以生效, 几乎是立刻就能检测到断网, 后来同事的一句话说出了真相:

    为啥你调setsockopt, 后面两个都是用SOL_TCP, 前面一个却用IPPROTO_TCP呢?

    马上改为SOL_TCP, 然后好使了....

    网上搜了下IPPROTO_TCP, 据说是每个linux系统的头文件可能不一样, 有的是用这个定义....

    呵呵(FUCK YOU)...

  • 相关阅读:
    学习进度笔记01
    进度报表十一
    进度报表十
    进度日报九
    进度日报八
    进度日报七
    第七周总结
    进度报表六
    第一阶段冲刺6
    第一阶段冲刺5
  • 原文地址:https://www.cnblogs.com/chaoswong/p/5507475.html
Copyright © 2011-2022 走看看