Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets QTcpSocket保持活动选项不起作用_Sockets_Keep Alive_Linux Mint_Qtcpsocket - Fatal编程技术网

Sockets 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

我有一个简单的程序作为我的客户端,它由一个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);
/// 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:
        // ...
        // ...
    }
}