最近需要寫一個linux下的通信程序, 通信模塊用的是Qt的QTcpSocket.
最后程序需要增加一個斷網檢測, 在windows下調試沒問題, 拔網線, 斷網口都能馬上檢測到, 但到了部署到linux下就需要等10多分鍾才能得到斷網的信號.
調試+google后, 定位問題應該不是Qt的問題, 而是windows和linux下對tcp超時的設置不同導致的, 也找到一些解決方案, 大致可以歸納為兩類:
- 直接修改系統參數的(鏈接)
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
- 在程序里修改參數的 (鏈接)
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)...