1
votes

When using QNetworkAccessManager I get a strange error that only occurs on some systems but not others.

See below for the code. The test below connects to an SSL-based site.

I have OpenSSL DLLs (libeay32.dll and ssleay32.dll) on the client systems in the same directory as my application but the error still occurs.

The error code is (99) – Unknown Network Error.

What causes this error on some systems but not others?

What can I do to fix?

Thank you for your time.

In the constructor of the application: MainNetConnector = new QNetworkAccessManager(this);

The function that starts the test:

void QTBasicWidget::performNetworkTest() {

    QMessageBox::StandardButton RequestNetworkTest;

    RequestNetworkTest = QMessageBox::information(this, "Would you like to initiate a network test?",
        "Would you like to perform a network test?\n\nThe application will test the network for connectivity to and from the licensing server specified.\n\nResults will be displayed in the 'Log' tab.",
        QMessageBox::Yes | QMessageBox::No);

    QNetworkRequest req;

    QByteArray postData;

    QNetworkReply* reply;

    switch (RequestNetworkTest) {

    case QMessageBox::Yes:

        LoggingWidget->logText(tr("Beginning the network test."));

        if (UseSecuredURL) {

            req.setUrl(QUrl(SecureURL + "testconnection.php"));

            LoggingWidget->logText(tr("Connecting to secure URL: ") + SecureURL + tr("testconnection.php"));

        }
        else {

            req.setUrl(QUrl(UnsecureURL + "testconnection.php"));

            LoggingWidget->logText(tr("Connecting to unsecure URL: ") + UnsecureURL + tr("testconnection.php"));

        }

        MainNetConnector->setCookieJar(new QNetworkCookieJar(MainNetConnector));

        LoggingWidget->logText(tr("Cookie jar prepared for data to send."));

        reply = MainNetConnector->post(req, postData);

        LoggingWidget->logText(tr("Data sent."));

        connect(reply, &QNetworkReply::finished, this, &QTBasicWidget::processTestResults);
        connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
            this, SLOT(networkError(QNetworkReply::NetworkError)));

        if (TestingTimer) {

            TestingTimer->stop();
            TestingTimer->deleteLater();
            TestingTimer = NULL;

        }

        TestingTimer = new QTimer(this);
        connect(TestingTimer, SIGNAL(timeout()), this, SLOT(onDelayedNetworkTestReponse()));
        TestingTimer->start(5000);

        break;

    case QMessageBox::No:

        QMessageBox::information(this, "Test cancelled.",
            "Network test cancelled.",
            QMessageBox::Ok);

        break;

    default:

        QMessageBox::information(this, "Test cancelled.",
            "Network test cancelled.",
            QMessageBox::Ok);

        break;

    }

}

The function that received the results of the test:

void QTBasicWidget::processTestResults() {

    if (TestingTimer) {

        TestingTimer->stop();
        TestingTimer->deleteLater();
        TestingTimer = NULL;

    }

    LoggingWidget->logText(tr("Reply received."));
    auto reply = qobject_cast< QNetworkReply *>(sender());
    QByteArray bytes = reply->readAll();
    QString str = QString::fromUtf8(bytes.data(), bytes.size());

    LoggingWidget->logText(tr("Raw data from reply: ") + str);

    GLint statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

    LoggingWidget->logText(tr("Reply status code: ") + QString::number(statusCode));

    if (statusCode == 200) {

        QMessageBox::StandardButton NetworkTestResults;

        NetworkTestResults = QMessageBox::information(this, "Test succeeded!.",
            "Network test succeeded.",
            QMessageBox::Ok);

    }
    else {

        QMessageBox::StandardButton NetworkTestFailed;

        NetworkTestFailed = QMessageBox::critical(this, "Test failed!.",
            "Network test failed.",
            QMessageBox::Ok);

    }

}

And the error-handling function: void QTBasicWidget::networkError(QNetworkReply::NetworkError err) {

    if (CurrentlyDebugging) {

        LoggingWidget->logText(tr("Network error. Error code is: ") + QString::number(err));

    }

    QMessageBox::StandardButton CriticalMessageBox;

    CriticalMessageBox = QMessageBox::critical(this, tr("Licensing Server Error"),
        tr("Specific error code was (") + QString::number(err) + tr(")"), QMessageBox::Ok);

}
2
Some locked down networks don't allow https or ssl connections to every kind of site or port. I was recently using a public/guest connection at an institution that blocked using any VPN software (at least with the default port configuration). Do you have any more information about the network setup of the clients that are failing? Or rather, have you confirmed that it isn't related to the way those computers are accessing the network? Is the firewall turned off? - phyatt
@phyatt I know on one of my coworker's system that experiences this problem he has his firewall turned off and is using his home broadband connection. - user3434662
@phyatt You raise good points; the site I am connecting to uses 443, most system don't block that and I am getting too many clients complaining to say that a simple firewall block like that is the issue. - user3434662

2 Answers

1
votes

http://doc.qt.io/qt-5/qtnetwork-downloadmanager-example.html

http://doc.qt.io/qt-5/qtnetwork-download-example.html

It looks like you probably should check for SSL errors, too.

Hopefully this is a consistent bug, that you can find what is going on. My best guess is that it is SSL related. The downloader examples show how to view these errors.

#ifndef QT_NO_SSL
    connect(reply, SIGNAL(sslErrors(QList<QSslError>)), SLOT(sslErrors(QList<QSslError>)));
#endif

// ...

void DownloadManager::sslErrors(const QList<QSslError> &sslErrors)
{
#ifndef QT_NO_SSL
    foreach (const QSslError &error, sslErrors)
        fprintf(stderr, "SSL error: %s\n", qPrintable(error.errorString()));
#else
    Q_UNUSED(sslErrors);
#endif
}

Hope that helps.

0
votes

Using "C:\Qt\MaintenanceTool.exe" Add or remove components In Qt > Developer and Designer Tool > OpenSSL x.y.z Toolkit

Copy all DLL from the following directory, in the directory of your EXE file. C:\Qt\Tools\OpenSSL\Win_x64\bin