QTcpSocket Keep alive option does not work

8.5k views Asked by At

I have a simple program as my client consisting a tcp socket (QTcpSocket). Codes for my client are given below:

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);

which setSocketOption is also given below:

/// 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));

when I run my program, everything is look fine and keepalive option will be enabled for my socket. But it does not work when I unplug my cable on client side. I have brought my netstat output below which incdicate that keepalive timer has enabled for my socket.

tcp        0      0 192.168.2.157:37281     192.168.2.163:4444      ESTABLISHED keepalive (0.16/0/0)

I have also enabled keepalive option on server side exactly like client side. Now I have some questions; 1- When I should enable keepalive option? After connecting to server or before connecting? 2- Should I write some code for catching keepalive error in my program?

By the way, my program is running in linux mint 17.1 and I also changed keeplalive options in sysctl.conf and proc/sys to no vail.

Thanks in advance for your helps. Reza

1

There are 1 answers

8
Vladimir Bershov On BEST ANSWER

It would be better to use Qt's function setSocketOption:

your_socket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);

enum QAbstractSocket::SocketOption

This enum represents the options that can be set on a socket. If desired, they can be set after having received the connected() signal from the socket or after having received a new socket from a QTcpServer.

Note: On Windows Runtime, QAbstractSocket::KeepAliveOption must be set before the socket is connected.

and for catch any connection errors:

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:
        // ...
        // ...
    }
}