Sockets QTcpSocket保持活动选项不起作用
我有一个简单的程序作为我的客户端,它由一个tcp套接字(QTcpSocket)组成。我的客户代码如下所示:Sockets QTcpSocket保持活动选项不起作用,sockets,keep-alive,linux-mint,qtcpsocket,Sockets,Keep Alive,Linux Mint,Qtcpsocket,我有一个简单的程序作为我的客户端,它由一个tcp套接字(QTcpSocket)组成。我的客户代码如下所示: while (tcpSocket.data()->waitForConnected(maxWaitingTimeToConnect) == false) { tcpSocket.data()->connectToHost(serverIP, serverPort); if (maxRetryNumberToConnect != -1 && ret
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);
/// 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选项,与客户端完全相同。现在我有一些问题;1-何时启用keepalive选项?连接到服务器之后还是连接之前?2-我应该写一些代码来捕捉程序中的keepalive错误吗
顺便说一句,我的程序运行在LinuxMint17.1中,我还将sysctl.conf和proc/sys中的keeplalive选项更改为NoVail
提前感谢你的帮助。
Reza最好使用Qt的功能: 枚举QAbstractSocket::SocketOption 此枚举表示可以在套接字上设置的选项。如果 如果需要,可以在收到connected()信号后进行设置 从插座或在收到来自的新插座后 qtcserver 注意:在Windows运行时,必须在连接套接字之前设置QAbstractSocket::KeepAliveOption 对于捕获任何连接错误:
connect (your_socket, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error), this, &YourClass::onError);
// ...
void YourClass::onError(QAbstractSocket::SocketError socketError)
{
switch(socketError)
{
case QAbstractSocket::ConnectionRefusedError:
// ...
// ...
}
}
connect(您的\u套接字、静态\u转换(&QAbstractSocket::error)、this和YourClass::onError);
// ...
void YourClass::onError(QAbstractSocket::socketterror socketterror)
{
开关(插座错误)
{
案例QAbstractSocket::ConnectionRefusedError:
// ...
// ...
}
}
您发布的netstat
输出表明它确实有效。不清楚你在问什么。可能是重复的。你提到过这个。作为替代方案,您也可以考虑使用各种waitfor…()
方法(即waitForReadyRead(毫秒)
)。可以将超时设置为所需的量,然后检查连接是否处于活动状态。顺便说一句,我是新来的Qt。你找到解决实际问题的办法了吗@EJP,我认为OP存在一个问题,即即使拔出互联网插头(如果我理解正确的话),插座也不会断开。为什么会更好?@EJP,因为Qt有自己的功能,在这种情况下混合使用Qt和系统功能是很奇怪的。此外,Qt是一个跨平台框架相关产品。如果setsockopt()
没有返回-1,它显然已经工作了,那么这将如何解决OP的问题呢?setsocket返回0,这意味着它是真的。我还尝试了Qt提供的setSocketOption,但它并没有解决我的问题。另外,如何使用此功能设置其他选项,如空闲时间?它只启用了keepalive选项。@VladimirBershov我也会像您建议的代码一样连接套接字错误,但它在我的情况下不起作用。当我拔下电缆时,服务器可以理解,但客户端不能。我想我的问题是我为套接字设置的值。
your_socket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
connect (your_socket, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error), this, &YourClass::onError);
// ...
void YourClass::onError(QAbstractSocket::SocketError socketError)
{
switch(socketError)
{
case QAbstractSocket::ConnectionRefusedError:
// ...
// ...
}
}