【发布时间】:2016-12-20 08:50:13
【问题描述】:
我有一个简单的程序作为我的客户端,它包含一个 tcp 套接字 (QTcpSocket)。我的客户的代码如下:
while (tcpSocket.data()->waitForConnected(maxWaitingTimeToConnect) == false)
{
tcpSocket.data()->connectToHost(serverIP, serverPort);
if (maxRetryNumberToConnect != -1 && retryNumber++ > maxRetryNumberToConnect)
{
qDebug() << "Socket is disconnected and maximum try for re-connection reached.";
return false;
}
emit sgl_tryToConnect();
// Socket is disconnected and trying to re-connect
QThread::msleep(100);
}
qDebug() << "Client is connected";
qDebug() << tcpSocket.data()->localPort();
auto sd = tcpSocket.data()->socketDescriptor();
NetworkShared::setSocketOption(&sd);
下面还给出了哪个setSocketOption:
/// Set keepAlive
int enableKeepAlive = 1;
/* Set socket FD's option OPTNAME at protocol level LEVEL
to *OPTVAL (which is OPTLEN bytes long).
Returns 0 on success, -1 for errors. */
qDebug() << setsockopt(*socketDescriptor, SOL_SOCKET, SO_KEEPALIVE, &enableKeepAlive, sizeof(enableKeepAlive));
int maxIdle = 1; /// Seconds
qDebug() << setsockopt(*socketDescriptor, SOL_TCP, TCP_KEEPIDLE, &maxIdle, sizeof(maxIdle));
int count = 1; /// Send up to 1 keepalive packets out, then disconnect if no response
qDebug() << setsockopt(*socketDescriptor, SOL_TCP, TCP_KEEPCNT, &count, sizeof(count));
int interval = 1; /// Send a keepalive packet out every 1 seconds (after the 1 second idle period)
qDebug() << setsockopt(*socketDescriptor, SOL_TCP, TCP_KEEPINTVL, &interval, sizeof(interval));
当我运行我的程序时,一切看起来都很好,并且将为我的套接字启用 keepalive 选项。但是当我在客户端拔下电缆时它不起作用。我把我的 netstat 输出带到下面,表明我的套接字启用了 keepalive 计时器。
tcp 0 0 192.168.2.157:37281 192.168.2.163:4444 ESTABLISHED keepalive (0.16/0/0)
我还在服务器端启用了keepalive选项,就像客户端一样。现在我有一些问题; 1-我什么时候应该启用keepalive选项?连接到服务器之后还是连接之前? 2-我应该写一些代码来捕捉我的程序中的keepalive错误吗?
顺便说一句,我的程序在 linux mint 17.1 中运行,我还将 sysctl.conf 和 proc/sys 中的 keepalive 选项更改为无效。
提前感谢您的帮助。 雷扎
【问题讨论】:
-
您发布的
netstat输出表明它确实有效。不清楚你在问什么。 -
你有没有提到这个QAbstractSocket::disconnected () signal does not emit when switch is disconnected。作为替代方案,您也可以考虑使用各种
waitfor...()方法(即waitForReadyRead(milliseconds))。可以将超时设置为所需的量,然后在此期间还检查连接是否处于活动状态。顺便说一句,我是 Qt 的新手。您找到解决实际问题的方法了吗? @EJP,我认为 OP 有一个问题,即即使拔出互联网插头(如果我理解正确的话)插座也不会断开。
标签: sockets keep-alive linux-mint qtcpsocket