【问题标题】:QNetworkAccessManager Error Code 99; Only on Some Systems…QNetworkAccessManager 错误代码 99;仅在某些系统上...
【发布时间】:2015-03-18 02:27:42
【问题描述】:

使用 QNetworkAccessManager 时,我收到一个奇怪的错误,该错误仅在某些系统上发生,而在其他系统上不会发生。

请参阅下面的代码。下面的测试连接到一个基于 SSL 的站点。

我的客户端系统上有 OpenSSL DLL(libeay32.dllssleay32.dll),位于与我的应用程序相同的目录中,但错误仍然存​​在。

错误代码为 (99) – 未知网络错误。

是什么原因导致某些系统出现此错误,而其他系统则不然?

我能做些什么来解决?

感谢您的宝贵时间。

在应用程序的构造函数中: MainNetConnector = new QNetworkAccessManager(this);

启动测试的函数:

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;

    }

}

接收测试结果的函数:

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

    }

}

还有错误处理功能: 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);

}

【问题讨论】:

  • 一些锁定的网络不允许 https 或 ssl 连接到所有类型的站点或端口。我最近在一家阻止使用任何 VPN 软件(至少使用默认端口配置)的机构使用公共/访客连接。您是否有更多关于失败客户端的网络设置的信息?或者更确切地说,您是否确认这与这些计算机访问网络的方式无关?防火墙关闭了吗?
  • @phyatt 我知道我的一位同事的系统遇到了这个问题,他的防火墙已关闭并正在使用他的家庭宽带连接。
  • @phyatt 你提出了好点;我要连接的站点使用 443,大多数系统都不会阻止它,而且我有太多客户抱怨说像这样的简单防火墙阻止是问题所在。

标签: c++ qt ssl openssl qnetworkaccessmanager


【解决方案1】:

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

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

看来您也应该检查 SSL 错误。

希望这是一个一致的错误,您可以找到正在发生的事情。我最好的猜测是它与 SSL 相关。下载器示例展示了如何查看这些错误。

#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
}

希望对您有所帮助。

【讨论】:

  • 如果您在使用 openssl 1.0 的机器上构建 Qt5.12,然后在使用 openssl 1.1 的机器上运行它,您将收到此消息((99) – 未知网络错误。)。恐怕你不会得到更多关于 sslErrors 的诊断信息。当 Qt 调用一个不存在的 ssl 函数时,它似乎会发生(它将 ssl 代码作为插件加载)。特别是,如果您在 RHEL 7 上构建 Qt5.12,然后尝试在 RHEL 8 上运行,就会发生这种情况。在这种情况下,您可以运行“dnf install compat-openssl50”并继续前进。不过不知道你会在 Windows 上做什么。
  • 呃,它是 compat-openssl10 但我无法编辑我的评论
【解决方案2】:

使用“C:\Qt\MaintenanceTool.exe” 添加或删除组件 在 Qt 中 > 开发者和设计者工具 > OpenSSL x.y.z 工具包

从以下目录复制所有 DLL,在您的 EXE 文件目录中。 C:\Qt\Tools\OpenSSL\Win_x64\bin

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-23
    • 1970-01-01
    • 2012-01-07
    • 2012-06-28
    相关资源
    最近更新 更多