TLS对GET请求的初始化失败

时间:2018-12-16 19:25:51

标签: c++ json qt

我从qt / c ++开始,在我的项目中,我需要进行json post / get / put操作,但是我尝试执行一个简单的get请求,但出现错误:qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed

我不知道为什么,我尝试了一些方法,但是都发出了相同的信息。我附上了我使用的代码。

mainwindow.cpp:

void MainWindow::replyFini(QNetworkReply* reply)
{
    QString answer = QString::fromUtf8(reply->readAll());
    qDebug() << "answer------------>"<<answer;
}

void MainWindow::on_btn_login_clicked()
{
    QNetworkRequest request(QUrl("https://httpbin.org/get"));
    QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFini(QNetworkReply*)));
    manager->get(request);
}

mainwindow.h:

#include <QtCore>
#include <QNetworkAccessManager>
#include <QNetworkReply>

3 个答案:

答案 0 :(得分:2)

对我有用的是从https://slproweb.com/products/Win32OpenSSL.html下载OpenSSL简易版(适用于我的编译器),然后将libcrypto和libssl DLLs从c:\ Program Files \ OpenSSL \复制到程序的.exe文件夹。

答案 1 :(得分:2)

在Windows上,如果通过在线安装程序安装Qt,则可以选择OpenSSL Toolkit作为可选组件。这应该为您提供绝对与您的Qt兼容的版本。

如果在安装过程中未选中它,则可以重新运行C:\Qt\MaintenanceTool.exe并选择“添加或删除组件”。 OpenSSL Toolkit位于“开发人员和设计人员工具”部分下,它是最后一个条目。

但是,边栏中有一个注释:

  

Qt安装程序未设置OpenSSL环境。用户需要定义路径和环境变量。

因此,安装后,应将包含DLL的目录添加到PATH环境变量中,或将所需的DLL放在.exe文件附近(将它们复制到debugrelease目录中项目)。

该目录位于C:\Qt\Tools\OpenSSL\Win_x64\bin(如果需要32位版本,则位于Win_x86)。在我的情况下,这些DLL分别命名为libssl-1_1-x64.dlllibcrypto-1_1-x64.dll


但这还不足以将其部署到另一台计算机上,在将其全部复制后,我再次遇到相同的错误。原因是OpenSSL DLL依赖于Qt应用程序本身之外的另一个MSVC运行时版本,并且这些错误未报告。在Dependency Walker中打开这些DLL,以查找丢失的内容。就我而言,它是MSVCR100.dll,所以我必须安装MSVC 2010 Redistributable x64x86 is here)。

答案 2 :(得分:1)

找不到SSL库。该错误可以在Qt Src中读出。要么与您的应用程序一起部署它们,要么在您的计算机上安装OpenSSL。

还有一个小提示:

void MainWindow::replyFini(QNetworkReply* reply)
{
    QString answer = QString::fromUtf8(reply->readAll());
    qDebug() << "answer------------>"<<answer;
}

您应该致电reply->deleteLater();

void MainWindow::on_btn_login_clicked()
{
    QNetworkRequest request(QUrl("https://httpbin.org/get"));
    QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFini(QNetworkReply*)));
    manager->get(request);
}

添加connect(manager, &QNetworkAccessManager::finished, manager, &QNetworkAccessManager::deleteLater);,以避免每次点击都会导致内存泄漏。