TcpSock的心跳问题
来源:互联网 发布:苹果软件不可用 编辑:程序博客网 时间:2024/04/29 05:34
- 前言
- 原理
- 解决办法
- tcp socket的心跳属性设置
- 操作系统间的差异
- macos的特殊情形
- 总结
前言
tcp socket建立连接之后,突然拔掉网线,或者把路由器断电。tcp socket并不会立即报错断开。
原理
tcp其实有这个属性,但是默认没有打开。
本文只是介绍如何解决问题;至于问题背后的原理啥的,我就不说了。
解决办法
1,自己定义心跳消息。
这个还好,自己控制。但是不建议自己实现。
不知道为什么,现在越来越懒了。已经存在的轮子就不要再重复制造了,再说了,自己实现的未必有别人的好,面临的问题一大把。
2,使用tcp socket的属性。
tcp socket的心跳属性设置
相关的参数:
1,是否打开心跳属性
2,当没有数据交换时,等待多久才发送心跳
3,心跳的发送周期。两次心跳的时间间隔
4,心跳的发送次数。发送几次之后,socket就会产生断开连接的信号。
操作系统间的差异
虽然说都是tcp socket,但是不同操作系统之间的还真不一样。
android跟linux是一样的。
macos不行,貌似必须要用管理员权限。
#ifdef Q_OS_WIN#include "WinSock2.h"#include <winsock2.h>#include <ws2tcpip.h>#include "mstcpip.h"#endif#ifdef Q_OS_ANDROID#include <sys/socket.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include "netinet/tcp.h"#endifQTcpSocket *socket ;//你的socket指针int fd = socket->socketDescriptor();#ifdef Q_OS_WIN int keepAlive = 1; // 开启keepalive属性. 缺省值: 0(关闭)// int keepIdle = 60; // 如果在60秒内没有任何数据交互,则进行探测. 缺省值:7200(s)// int keepInterval = 5; // 探测时发探测包的时间间隔为5秒. 缺省值:75(s)// int keepCount = 2; // 探测重试的次数. 全部超时则认定连接失效..缺省值:9(次) int nRet = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char*)(&keepAlive), sizeof(keepAlive)); if(nRet == SOCKET_ERROR) { qDebug()<<"robin:setSocketopt failed"; } struct tcp_keepalive alive; alive.keepalivetime = 5000; // 开始首次KeepAlive探测前的TCP空闭时间 alive.keepaliveinterval = 1000; // 两次KeepAlive探测间的时间间隔 alive.onoff = TRUE; DWORD dwBytesRet=0; if (WSAIoctl(fd, SIO_KEEPALIVE_VALS, &alive, sizeof(alive), NULL, 0, &dwBytesRet, NULL, NULL) == SOCKET_ERROR) { qDebug()<<"robin:WSAIoctl failed"; return ; }#elif defined Q_OS_ANDROID int keepAlive = 1; // 开启keepalive属性. 缺省值: 0(关闭) int keepIdle = 5; // 如果在60秒内没有任何数据交互,则进行探测. 缺省值:7200(s) int keepInterval = 1; // 探测时发探测包的时间间隔为5秒. 缺省值:75(s) int keepCount = 5; // 探测重试的次数. 全部超时则认定连接失效..缺省值:9(次) setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void*)&keepAlive, sizeof(keepAlive));//确定打开tcp的这个属性 setsockopt(s, IPPROTO_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle)); setsockopt(s, IPPROTO_TCP, TCP_KEEPINTVL, (void*)&keepInterval, sizeof(keepInterval));//每次发送间隔时间 setsockopt(s, IPPROTO_TCP, TCP_KEEPCNT, (void*)&keepCount, sizeof(keepCount));//探测重试的次数#elif defined Q_OS_MACOS//mac还没有找到合适的办法,//主要设置的有三个值// int keepIdle = 5; // 如果在60秒内没有任何数据交互,则进行探测. 缺省值:7200(s)// int keepInterval = 1; // 探测时发探测包的时间间隔为5秒. 缺省值:75(s)// int keepCount = 5; // 探测重试的次数. 全部超时则认定连接失效..缺省值:9(次) qDebug()<<"robin:waring, macos not set tcpsocket heartbeta";#else qDebug()<<"robin:waring,not set tcpsocket heartbeta";#endif
macos的特殊情形
用控制台查看当前tcpsocket属性
#sysctl -A | grep net.inet.tcp.*keep
输出
robindeMBP:~ robin$ sysctl -A | grep net.inet.tcp.*keepnet.inet.tcp.keepidle: 7200000net.inet.tcp.keepintvl: 75000net.inet.tcp.keepinit: 75000net.inet.tcp.always_keepalive: 0net.inet.tcp.keepcnt: 8
用命令更改
sudo sysctl -w net.inet.tcp.keepidle=20000sudo sysctl -w net.inet.tcp.keepintvl=20000sudo sysctl -w net.inet.tcp.keepinit=20000sudo sysctl -w net.inet.tcp.always_keepalive=1
如果用代码,会发现有的值设置不了。
#ifdef Q_OS_MACOS#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include "netinet/tcp.h"#endif setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(void*)&keepAlive, sizeof(keepAlive));//确定打开tcp的这个属性 // setsockopt(s, IPPROTO_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle)); setsockopt(s, IPPROTO_TCP, TCP_KEEPINTVL, (void*)&keepInterval, sizeof(keepInterval));//每次发送间隔时间 setsockopt(s, IPPROTO_TCP, TCP_KEEPCNT, (void*)&keepCount, sizeof(keepCount));//探测重试的次数
也就是说,心跳初始等待的时间没有找到对应的宏,二者值默认是7200s。如果不设置这个值的话,基本没什么用了。
总结
windows、linux和android都找到了对应的实现方式。
macos没有找到,放弃了。
阅读全文
0 0
- TcpSock的心跳问题
- 关于网络心跳与磁盘心跳超时多久会引发节点重启的问题
- TaskTracker向JobTracker发送心跳时的问题
- Netty心跳程序遇到的2个问题
- mina 心跳包,断线重连的问题
- Android 心跳连接功能 bindService()无法启动Service的问题
- 谈下openfire心跳包检测的问题
- 芙蓉姐姐的心跳回忆
- 心跳服务器的设计
- DCOM的心跳
- DCOM的心跳
- DCOM的心跳
- DCOM的心跳
- DCOM的心跳
- JAVA的心跳包
- 玩的就是心跳
- 心跳包的编写
- hadoop的心跳回忆
- 将博客搬至CSDN
- 【工具】——SonarLint analysis failed:'other' has different root
- 事件轴-节点Two
- 61岁刘晓庆与75岁老公秀恩爱不减当年进军微商的气势!
- spring-boot pom管理
- TcpSock的心跳问题
- 汽水瓶
- 07_JNI Field Method Constructor_method Exception Memory
- Android7.0须知--应用间共享文件(FileProvider)
- 3、Spring技术栈-整合Log4j2
- 基于socket实现Android端和PC端服务器多文件传输
- PAT A 1114. Family Property (25)
- tensorflow 不使用GPU 无法利用GPU
- C2