当前位置: 代码网 > it编程>编程语言>C/C++ > Qt中https的使用,报错TLS initialization failed和不能打开ssl.lib问题解决

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

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

前言

在现代应用程序中,安全地传输数据变得越来越重要。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

包含相应的头文件: 

#include <qnetworkaccessmanager>
#include <qnetworkrequest>
#include <qnetworkreply>
#include <qcoreapplication>
#include <qnetworkaccessmanager>
#include <qnetworkrequest>
#include <qnetworkreply>
#include <qdebug>

int main(int argc, char *argv[]) {
    qcoreapplication app(argc, argv);

    // 创建网络访问管理器
    qnetworkaccessmanager manager;

    // 创建请求
    qnetworkrequest request(qurl("https://www.example.com"));
    request.setattribute(qnetworkrequest::followredirectsattribute, true);

    // 发起https get请求
    qnetworkreply *reply = manager.get(request);

    // 连接信号以处理响应
    qobject::connect(reply, &qnetworkreply::finished, [&]() {
        if (reply->error() == qnetworkreply::noerror) {
            qdebug() << "https request succeeded!";
            qdebug() << "response:" << reply->readall();
        } else {
            qdebug() << "https request failed with error:" << reply->errorstring();
        }
        reply->deletelater();
    });

    // 连接错误信号
    qobject::connect(reply, &qnetworkreply::erroroccurred, [&](qnetworkreply::networkerror error) {
        qdebug() << "error occurred:" << error;
    });

    // 启动事件循环
    return app.exec();
}

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

// 获取默认ssl配置
qsslconfiguration sslconfig = qsslconfiguration::defaultconfiguration();

// 自定义ssl配置,例如信任特定的ca证书
sslconfig.setpeerverifymode(qsslsocket::verifypeer);
sslconfig.setprotocol(qssl::tlsv1_2); // 指定使用tls 1.2协议

// 应用ssl配置到请求
request.setsslconfiguration(sslconfig);

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

下载文件示例

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

mainwindows.h头文件中增加:

private:
    ui::mainwindow *ui;
    qtcpserver *server;
    qtcpsocket *clientsocket;
    qnetworkaccessmanager *networkmanager;
    qnetworkreply *networkreply;
    qfile *m_file;
    qstring m_videourl;
}

void mainwindow::ondownloadprogress(qint64 bytesreceived, qint64 bytestotal)
{
    if (bytestotal > 0) {
        int progress = static_cast<int>((bytesreceived * 100) / bytestotal);
        ui->te_result->append(qstring("download progress: %1%").arg(progress));
        ui->progress->setvalue(progress);
    }
}

void mainwindow::onfinished()
{
    if (networkreply->error()) {
        ui->te_result->append(qstring("download failed: %1").arg(networkreply->errorstring()));
    } else {
        m_file->write(networkreply->readall());
        m_file->close();
        ui->te_result->append("download completed");
    }

    networkreply->deletelater();
    networkreply = nullptr;

    if (m_file) {
        m_file->deletelater();
        m_file = nullptr;
    }
}

void mainwindow::on_btndown_clicked()
{
    // 开始下载视频
    if(!m_videourl.isempty()){
        ui->te_result->append("begin download:");
      
        qurl url(m_videourl);
        qnetworkrequest request(url);
        networkreply = networkmanager->get(request);
        connect(networkreply, &qnetworkreply::downloadprogress, this, &mainwindow::ondownloadprogress);
        connect(networkreply, &qnetworkreply::finished, this, &mainwindow::onfinished);

        // 创建文件
        m_file = new qfile("downloaded_video.mp4", this);
        if (!m_file->open(qiodevice::writeonly)) {
            ui->te_result->append("failed to open file for writing");
            delete m_file;
            m_file = nullptr;
            return;
        }
    }else{
        ui->te_result->append("begin download:");
        ui->te_result->append("error,no videourl!");
        return;
    }

}

其他资源

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

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com