Qt: Why is `QAbstractSocket::error(QAbstractSocket::SocketError)` signal not generated when internet is disconnected?
Asked Answered
G

1

1

I am trying to achieve a signal when the internet is disconnected for an already connected SSL socket. Here is the way I have derived the QSslSocket:

struct CloudSSL::Socket : public QSslSocket
{
  Q_OBJECT public:

  void ConnectSlots ()
  {
    connect(this, SIGNAL(readyRead()), this, SLOT(ReceiveData()));
    connect(this, SIGNAL(disconnected()), this, SLOT(Disconnected()));
    // *** None of the above or below is invoking when internet disconnects ***
    connect(this, SIGNAL(error(QAbstractSocket::SocketError)),
            this, SLOT(Error(QAbstractSocket::SocketError)));
  }

  virtual ~Socket ()
  {
    QObject::disconnect();
    QSslSocket::abort();
  }

  public slots:
  void ReceiveData ()
  {
    LOG("Socket received data...");
  }

  void Disconnected ()
  {
    LOG("Socket got disconnected...");
  }

  void Error (QAbstractSocket::SocketError error)
  {
    LOG("Socket error ", error);
  }
}

Here is how it's initialized:

m_pSSLSocket = new Socket;
m_pSSLSocket->setProtocol(QSsl::TlsV1_2);
m_pSSLSocket->setLocalCertificateChain(QSslCertificate::fromPath(":/Certificate.pem", QSsl::Pem));
m_pSSLSocket->setPrivateKey(QSslKey(privateKeyFile.readAll(), QSsl::Rsa));
m_pSSLSocket->setSocketOption(QAbstractSocket::LowDelayOption, true);  // <---
m_pSSLSocket->setSocketOption(QAbstractSocket::KeepAliveOption, true);  // <---
m_pSSLSocket->connectToHostEncrypted(SAARATHY_URL, SAARATHY_PORT);
m_pSSLSocket->ignoreSslErrors();

Things work fine in general. However, if I disable wifi in my Ubuntu PC, then I don't get any network error as expected from the QAbstractSocket::SocketError:

QAbstractSocket::NetworkError -- 7 -- An error occurred with the network (e.g., the network cable was accidentally plugged out).

Referred following posts before this Qn:

Question: What is the Qt exclusive way of receiving a signal when the internet is disconnected?

Grith answered 28/6, 2017 at 12:55 Comment(0)
N
2

Unless the protocols you use have some sort of keep-alive, if you don't send anything nothing will be sent and no attempt of error checking will be done.

If you want to see if there's problem with a connection you actually have to send something. If a cable is unplugged or there is any other problem between you and the remote host, then (after a suitable timeout and retries) you will get an error.

To see if the remote host has closed the connection in a nice way, you have to attempt to read something, in which case the receive call will return that it has read zero bytes.

Nonet answered 28/6, 2017 at 12:59 Comment(1)
Q1: My earlier implementation (before porting to Qt) was implemented using the technique described in this answer. That worked perfectly fine, where I could set a timeout option for when to notify on internet disconnection. Is there any such built-in facility within Qt? Q2: (title Qn) Why the error(...) is not signalled with QAbstractSocket::NetworkError on its own as described in the Qt page?Grith

© 2022 - 2025 — McMap. All rights reserved.