• Qt中https的使用,报错TLS initialization failed和不能打开ssl.lib问题解决


    前言

    在现代应用程序中,安全地传输数据变得越来越重要。Qt提供了一套完整的网络API来支持HTTP和HTTPS通信。然而,在实际开发过程中,开发者可能会遇到SSL相关的错误,例如“TLS initialization failed”,cant't open ssl.lib等问题。本文将介绍如何在Qt中使用HTTPS进行网络访问,网上搜到的结果大都是错的。这里并提供解决TLS初始化失败和SSL库问题的方法。

    一、Qt中使用HTTPS的基本概念

    Qt使用QNetworkAccessManagerQNetworkReply类来处理网络请求。对于HTTPS请求,Qt会自动使用SSL/TLS进行加密通信。以下是使用HTTPS的基本步骤:

    1. 创建QNetworkAccessManager实例。
    2. 使用get()post()等方法发起请求。
    3. 连接finished()信号以处理响应。
    4. 检查QNetworkReply的状态和错误。

    二、TLS初始化失败的原因

    TLS初始化失败通常是因为Qt没有正确配置或找到SSL库。这可能是由于以下原因:

    • 缺少必要的SSL库文件。
    • 编译Qt时未启用SSL支持。
    • 系统环境变量未正确设置。

    三、解决TLS初始化失败的步骤

    确保你的项目中包含了网络模块(corenetwork模块通常默认包含SSL支持)。

    注意,你的yourprj.pro工程文件配置中只需要: QT += network即可。不需要向网上说的那样又是配置CONFIG += openssl又是增加LIBS += -Llib -lssl -lcrypto。这样搞反倒是错的,会报can't open ssl.lib。其实关于ssl的库qt安装时已经包含了,编译时也会自动链接成功,编译成功。

    在你的Qt应用程序中,尝试创建一个QSslSocketQSslConfiguration对象,并使用它来发起HTTPS请求。如果Qt支持SSL,这些类应该能够正常使用。能否编译通过,编译通过则没问题。

    唯一需要注意的是:

    运行后访问https报错,提示TLS initialization failed。这是因为qt自带的libssl-1_1.dll很扯,位置在Qt\Qt5.14.2\Tools\QtCreator\bin\libssl-1_1.dll, 是个32位的库,提供还不提供全啊,缺少64位的库。咋知道它是32位的库?简单办法文本打开后看到PE..L....的内容,说明它是32位的库(64位的库打开后看二进制能看到PE..d..的内容)。解决办法也简单,网上找到64位的库,名字叫libssl-1_1-x64.dll 和libcrypto-1_1-x64.dll,下载后把它放入你的工具链的bin目录下,我的是在 Qt\Qt5.14.2\5.14.2\msvc2017_64\bin下。

    简单使用

    以下是一个简单的示例,展示如何在Qt中发起HTTPS请求:

    首先在工程的pro文件中,增加:

    QT += network

    包含相应的头文件: 

    1. #include
    2. #include
    3. #include
    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. int main(int argc, char *argv[]) {
    7. QCoreApplication app(argc, argv);
    8. // 创建网络访问管理器
    9. QNetworkAccessManager manager;
    10. // 创建请求
    11. QNetworkRequest request(QUrl("https://www.example.com"));
    12. request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
    13. // 发起HTTPS GET请求
    14. QNetworkReply *reply = manager.get(request);
    15. // 连接信号以处理响应
    16. QObject::connect(reply, &QNetworkReply::finished, [&]() {
    17. if (reply->error() == QNetworkReply::NoError) {
    18. qDebug() << "HTTPS request succeeded!";
    19. qDebug() << "Response:" << reply->readAll();
    20. } else {
    21. qDebug() << "HTTPS request failed with error:" << reply->errorString();
    22. }
    23. reply->deleteLater();
    24. });
    25. // 连接错误信号
    26. QObject::connect(reply, &QNetworkReply::errorOccurred, [&](QNetworkReply::NetworkError error) {
    27. qDebug() << "Error occurred:" << error;
    28. });
    29. // 启动事件循环
    30. return app.exec();
    31. }

    示例中并没有设置SSL配置,因为大多数情况下Qt会自动处理SSL配置。不配置也行。但是,如果你需要自定义SSL配置,可以这样: 

    1. // 获取默认SSL配置
    2. QSslConfiguration sslConfig = QSslConfiguration::defaultConfiguration();
    3. // 自定义SSL配置,例如信任特定的CA证书
    4. sslConfig.setPeerVerifyMode(QSslSocket::VerifyPeer);
    5. sslConfig.setProtocol(QSsl::TlsV1_2); // 指定使用TLS 1.2协议
    6. // 应用SSL配置到请求
    7. request.setSslConfiguration(sslConfig);

    自定义SSL配置通常只在需要特殊配置的情况下使用,例如在自签名证书或特定协议版本的情况下。对于大多数HTTPS请求,Qt的默认配置足够。 

    下载文件示例

    实现一个通过https链接下载文件的功能:

    mainwindows.h头文件中增加:

    1. private:
    2. Ui::MainWindow *ui;
    3. QTcpServer *server;
    4. QTcpSocket *clientSocket;
    5. QNetworkAccessManager *networkManager;
    6. QNetworkReply *networkReply;
    7. QFile *m_file;
    8. QString m_videoUrl;
    9. }
    1. void MainWindow::onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
    2. {
    3. if (bytesTotal > 0) {
    4. int progress = static_cast<int>((bytesReceived * 100) / bytesTotal);
    5. ui->te_result->append(QString("Download progress: %1%").arg(progress));
    6. ui->progress->setValue(progress);
    7. }
    8. }
    9. void MainWindow::onFinished()
    10. {
    11. if (networkReply->error()) {
    12. ui->te_result->append(QString("Download failed: %1").arg(networkReply->errorString()));
    13. } else {
    14. m_file->write(networkReply->readAll());
    15. m_file->close();
    16. ui->te_result->append("Download completed");
    17. }
    18. networkReply->deleteLater();
    19. networkReply = nullptr;
    20. if (m_file) {
    21. m_file->deleteLater();
    22. m_file = nullptr;
    23. }
    24. }
    25. void MainWindow::on_btnDown_clicked()
    26. {
    27. // 开始下载视频
    28. if(!m_videoUrl.isEmpty()){
    29. ui->te_result->append("begin download:");
    30. QUrl url(m_videoUrl);
    31. QNetworkRequest request(url);
    32. networkReply = networkManager->get(request);
    33. connect(networkReply, &QNetworkReply::downloadProgress, this, &MainWindow::onDownloadProgress);
    34. connect(networkReply, &QNetworkReply::finished, this, &MainWindow::onFinished);
    35. // 创建文件
    36. m_file = new QFile("downloaded_video.mp4", this);
    37. if (!m_file->open(QIODevice::WriteOnly)) {
    38. ui->te_result->append("Failed to open file for writing");
    39. delete m_file;
    40. m_file = nullptr;
    41. return;
    42. }
    43. }else{
    44. ui->te_result->append("begin download:");
    45. ui->te_result->append("error,no videoUrl!");
    46. return;
    47. }
    48. }

    其他资源

    QT5.14.2使用webkit引擎完成网页浏览-腾讯云开发者社区-腾讯云 

  • 相关阅读:
    2D-Driven 3D Object Detection in RGB-D Images
    【PyTorch深度学习项目实战100例】—— 基于MFCC对GTZAN音乐流派分类 | 第66例
    数字IC必学之《Skill入门教程》
    java垃圾回收
    Linux进程调度
    vue项目分环境配置打包处理
    韶关517功能水稻测产 国稻种芯-何登骥:中国水稻节广东活动
    Python编程经典案例【考题】排列组合
    uniapp-vue3-微信小程序-标签选择器wo-tag
    MallBook联合人民交通出版社,推动驾培领域新发展,开启驾培智慧交易新生态
  • 原文地址:https://blog.csdn.net/qq8864/article/details/140403398