简述
对于正在连接的Tcp网络通信程序中,因为由于某些情况下会出现连接中断,需要心跳检测机制来探测对方是否在线或者维持网络连接需要。而通常的实现方式是自己写代码使用心跳包的形式,这样子就显得代码复杂化,难以控制和管理。在Tcp中其实也有类似的机制,就是TCP保活机制。
SO_KEEPALIVE
使用::setsockopt设置Tcp属性后,在程序中表现为:当TCP检测到对端socket不再可用时(不能发出探测包,或探测包没有收到ACK的响应包),select会返回socket可读,并且在recv时返回-1,同时置上 errno 为 ETIMEDOUT.
void MTcpClient::setSocketKeepAlive()
{
int iSocket = (int)this->socketDescriptor();
if (iSocket < 0) return;
int iKeepAlive = 1; //开启/关闭keepalive属性
int iKeepIdle = 5; //如该连接在5秒内没有任何数据往来, 则进行探测
int iKeepInterval = 1; //探测时发包的时间间隔为1秒
int iKeepCount = 3; //探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发
socklen_t iLen = sizeof(socklen_t);
::setsockopt(iSocket, SOL_SOCKET, SO_KEEPALIVE, (void *)&iKeepAlive, iLen);
::setsockopt(iSocket, SOL_TCP, TCP_KEEPIDLE, (void*)&iKeepIdle, iLen);
::setsockopt(iSocket, SOL_TCP, TCP_KEEPINTVL, (void *)&iKeepInterval, iLen);
::setsockopt(iSocket, SOL_TCP, TCP_KEEPCNT, (void *)&iKeepCount, iLen);
}
MTcpClient继承QTcpClient,所以可以通过this->socketDescriptor()获取套接字对象。