万有斥力 发表于 2024-5-13 20:03:16

C++ Qt开发:QNetworkAccessManager网络接口组件

Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用步伐,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用QNetworkAccessManager组件实现Web网页访问。
QNetworkAccessManager是Qt网络模块中的关键类,用于管理网络访问和请求。作为一个网络请求的调治中心,它为Qt应用步伐提供了发送和接收各种类型的网络请求的能力,包括常见的GET、POST、PUT、DELETE等。这个模块的核心功能在于通过处理QNetworkReply和QNetworkRequest来实现与网络资源的交互。
通过QNetworkAccessManager,Qt应用步伐能够轻松地与远程服务器通讯,获取数据或将数据上传到服务器。这种网络请求的管理不仅是异步的,以确保不会壅闭主线程,还提供了丰富的信号和槽机制,使得开发者可以灵活地处理不同阶段的网络操作。
通常,QNetworkAccessManager会与QNetworkReply和QNetworkRequest一起利用。QNetworkRequest用于封装和配置网络请求的各种属性,例如URL、请求头等。而QNetworkReply则代表了对网络请求的相应,包含了请求返回的数据和相关信息。这三者共同协作,为Qt应用步伐提供了便捷、灵活且强大的网络通讯能力。
1.1 通用API函数

1.1.1 QNetworkAccessManager

要想实现网络通讯首先需要新建一个网络访问管理器,以下是QNetworkAccessManager类中的一些常用函数及其描述:
函数描述QNetworkAccessManager(QObject *parent = nullptr)构造函数,创建一个QNetworkAccessManager实例。virtual ~QNetworkAccessManager()虚析构函数,释放QNetworkAccessManager实例。QNetworkReply *get(const QNetworkRequest &request)发送GET请求,并返回与请求关联的QNetworkReply对象。QNetworkReply *post(const QNetworkRequest &request, QIODevice *data)发送POST请求,并返回与请求关联的QNetworkReply对象。QNetworkReply *post(const QNetworkRequest &request, const QByteArray &data)发送POST请求,并返回与请求关联的QNetworkReply对象。QNetworkReply *put(const QNetworkRequest &request, QIODevice *data)发送PUT请求,并返回与请求关联的QNetworkReply对象。QNetworkReply *put(const QNetworkRequest &request, const QByteArray &data)发送PUT请求,并返回与请求关联的QNetworkReply对象。QNetworkReply *deleteResource(const QNetworkRequest &request)发送DELETE请求,并返回与请求关联的QNetworkReply对象。QNetworkReply *head(const QNetworkRequest &request)发送HEAD请求,并返回与请求关联的QNetworkReply对象。QNetworkReply *sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data = nullptr)发送自定义请求,并返回与请求关联的QNetworkReply对象。QNetworkReply *sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, const QByteArray &data)发送自定义请求,并返回与请求关联的QNetworkReply对象。void setConfiguration(const QNetworkConfiguration &config)设置网络配置,用于定制网络举动。QNetworkConfiguration configuration() const获取当前网络配置。void clearAccessCache()扫除网络访问缓存。void setCache(QAbstractNetworkCache *cache)设置网络缓存。QAbstractNetworkCache *cache() const获取当前网络缓存。void setCookieJar(QNetworkCookieJar *cookieJar)设置用于管理HTTP cookie的QNetworkCookieJar。QNetworkCookieJar *cookieJar() const获取当前的HTTP cookie管理器。这些函数提供了QNetworkAccessManager的核心功能,使得开发者能够方便地进行各种类型的网络请求,配置网络参数,并进行相关的网络管理操作。
1.1.2 QNetworkReply

以下是QNetworkReply类中的一些常用函数及其描述:
函数描述QByteArray readAll() const读取所有可用的数据,并返回一个QByteArray,包含从网络复兴读取的所有内容。QByteArray peek(int maxSize) const查看最多maxSize字节的可用数据,但不从缓冲区中移除。QByteArray read(int maxSize)从网络复兴中读取最多maxSize字节的数据,并将其从缓冲区中移除。QByteArray readLine(int maxSize = 0)从网络复兴中读取一行数据,最多包含maxSize字节,并将其从缓冲区中移除。void ignoreSslErrors(const QList &errors = QList())忽略SSL错误,继承处理网络复兴。void abort()终止网络复兴的处理,关闭底层毗连。void close()关闭网络复兴的处理。QUrl url() const返回与网络复兴相关联的URL。QNetworkRequest request() const返回生成此网络复兴的网络请求。QNetworkAccessManager *manager() const返回与网络复兴相关联的QNetworkAccessManager。bool isFinished() const查抄网络复兴是否已完成。QNetworkReply::NetworkError error() const返回网络复兴的错误代码。bool hasRawHeader(const QByteArray &headerName) const查抄网络复兴是否包含指定原始头。QList rawHeaderList() const返回网络复兴的所有原始头的列表。QByteArray rawHeader(const QByteArray &headerName) const返回指定原始头的值。QVariant header(QNetworkRequest::KnownHeaders header) const返回指定标准头的值。QList rawHeaderValues(const QByteArray &headerName) const返回指定原始头的所有值。QVariant attribute(QNetworkRequest::Attribute code) const返回指定网络请求属性的值。QIODevice *readAllStandardOutput()读取标准输出的所有数据,并返回一个QIODevice,用于访问读取的内容。QIODevice *readAllStandardError()读取标准错误的所有数据,并返回一个QIODevice,用于访问读取的内容。bool isReadable() const查抄网络复兴是否可读取。这些函数提供了对QNetworkReply实例进行各种操作和查询的方法,包括读取复兴数据、处理SSL错误、获取请求信息、查抄错误状态等。开发者可以根据具体需求利用这些函数来有用地与网络复兴进行交互。
1.1.3 QNetworkRequest

以下是QNetworkRequest类中的一些常用函数及其描述:
函数描述QNetworkRequest(const QUrl &url)利用给定的URL构造一个QNetworkRequest实例。void setUrl(const QUrl &url)设置QNetworkRequest的URL。QUrl url() const返回与QNetworkRequest相关联的URL。void setRawHeader(const QByteArray &headerName, const QByteArray &headerValue)设置指定原始头的值。QByteArray rawHeader(const QByteArray &headerName) const返回指定原始头的值。bool hasRawHeader(const QByteArray &headerName) const查抄QNetworkRequest是否包含指定原始头。void setRawHeaderList(const QList &headerList)设置所有原始头的列表。QList rawHeaderList() const返回QNetworkRequest的所有原始头的列表。void setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)设置指定标准头的值。QVariant header(QNetworkRequest::KnownHeaders header) const返回指定标准头的值。void setAttribute(QNetworkRequest::Attribute code, const QVariant &value)设置指定网络请求属性的值。QVariant attribute(QNetworkRequest::Attribute code) const返回指定网络请求属性的值。void setSslConfiguration(const QSslConfiguration &config)设置SSL配置。QSslConfiguration sslConfiguration() const返回SSL配置。void setMaximumRedirectsAllowed(int maxRedirects)设置允许的最大重定向次数。int maximumRedirectsAllowed() const返回允许的最大重定向次数。void setOriginatingObject(QObject *object)设置发起此网络请求的对象。QObject *originatingObject() const返回发起此网络请求的对象。bool isEmpty() const查抄QNetworkRequest是否为空(未设置URL)。这些函数提供了对QNetworkRequest实例进行各种操作和查询的方法,包括设置和获取头信息、设置SSL配置、设置和获取网络请求属性等。开发者可以根据具体需求利用这些函数来有用地构建和管理网络请求。
1.2 实现Web页面访问

要利用该模块读者应该在*.pro文件内包含network网络模块,并在头文件中引入QNetworkAccessManager、QNetworkReply、QNetworkRequest三个类,在创建访问时首先利用QNetworkAccessManager新增一个manager管理类,并通过QNetworkRequest类创建一个GET请求地址,通过利用manager.get方法实现对特定页面的访问。
当访问完成时需要通过一个信号来实现对数据的处理,在QNetworkReply类中包含有如下表所示的信号以供读者利用,例如当访问被完成时则主动触发&QNetworkReply::finished完成信号,此时只需要对该信号进行相应的处理即可,通常会利用一个槽函数来处理它。
信号描述finished()当网络请求完成时发出。downloadProgress(qint64, qint64)在下载过程中定期发出,提供下载进度信息。参数为已下载的字节数和总字节数。uploadProgress(qint64, qint64)在上传过程中定期发出,提供上传进度信息。参数为已上传的字节数和总字节数。readyRead()当有可读取的数据时发出,用于关照应用步伐可以调用readAll()或read()方法以获取更多数据。error(QNetworkReply::NetworkError)当网络请求发生错误时发出,参数为错误代码。sslErrors(const QList &)当SSL错误发生时发出,参数为SSL错误的列表。这些信号提供了丰富的信息,使开发者能够在不同阶段处理网络请求。同理,在下载和上传过程中可以利用downloadProgress和uploadProgress信号来获取进度信息,readyRead信号表示有可读取的数据,error信号表示请求发生错误,sslErrors信号表示SSL相关的错误。
当信号被触发时则会通过QObject::connect毗连到对应的槽函数上,如下案例中所示,在槽函数内通过reply->attribute方法我们获取到此次相应码中的QNetworkRequest::HttpStatusCodeAttribute属性,该属性用来指明本次访问的状态值。此类属性也有许多可供参考,如下所示;
属性描述QNetworkRequest::HttpStatusCodeAttributeHTTP相应的状态码。QNetworkRequest::HttpReasonPhraseAttributeHTTP相应的原因短语,如"OK"、"Not Found"等。QNetworkRequest::RedirectionTargetAttribute重定向目标的URL。QNetworkRequest::ConnectionEncryptedAttribute毗连是否加密的标志,返回一个bool值。QNetworkRequest::SourceIsFromCacheAttribute请求是否来自缓存的标志,返回一个bool值。QNetworkRequest::HttpPipeliningAllowedAttribute是否允许HTTP流水线传输的标志,返回一个bool值。QNetworkRequest::HttpPipeliningWasUsedAttribute是否利用了HTTP流水线传输的标志,返回一个bool值。QNetworkRequest::CustomVerbAttribute自定义请求动作(HTTP verb)的字符串。QNetworkRequest::User用户自定义的属性,用于存储任意类型的用户数据。这些属性提供了额外的信息,使得开发者能够更全面地相识和处理网络相应。根据具体的应用需求,开发者可以选择利用这些属性中的一个或多个来获取所需的信息。
#include <QCoreApplication>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

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

    // 创建GET请求
    QNetworkRequest request(QUrl("http://www.baidu.com"));

    // 发送GET请求
    QNetworkReply *reply = manager.get(request);

    // 连接信号槽,处理响应
    QObject::connect(reply, &QNetworkReply::finished, [&]()
    {
      if (reply->error() == QNetworkReply::NoError)
      {
            // 获取请求的 URL
            qDebug() << "Request URL:" << reply->request().url();

            // 输出请求头信息
            qDebug() << "Request Headers:";
            QList<QByteArray> requestHeaders = reply->request().rawHeaderList();
            foreach (const QByteArray &header, requestHeaders) {
                qDebug() << header << ":" << reply->request().rawHeader(header);
            }

            // 获取响应码
            int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
            qDebug() << "HttpStatusCodeAttribute:" << statusCode;

            // 连接是否加密的标志
            bool connectionEncryptedAttribute = reply->attribute(QNetworkRequest::ConnectionEncryptedAttribute).toBool();
            qDebug() << "ConnectionEncryptedAttribute:" << connectionEncryptedAttribute;

            // 请求是否来自缓存的标志
            bool sourceIsFromCacheAttribute = reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool();
            qDebug() << "SourceIsFromCacheAttribute:" << sourceIsFromCacheAttribute;

            // HTTP请求是否被允许进行流水线处理的标志
            bool httpPipeliningAllowedAttribute = reply->attribute(QNetworkRequest::HttpPipeliningAllowedAttribute).toBool();
            qDebug() << "HttpPipeliningAllowedAttribute:" << httpPipeliningAllowedAttribute;

            // 输出响应头信息
            qDebug() << "Response Headers:";
            QList<QByteArray> responseHeaders = reply->rawHeaderList();
            foreach (const QByteArray &header, responseHeaders) {
                qDebug() << header << ":" << reply->rawHeader(header);
            }

            // 处理响应内容,这里可以使用 readAll() 方法获取响应内容
            // qDebug() << "Response Content:" << reply->readAll();
      } else
      {
            qDebug() << "Error:" << reply->errorString();
      }

      // 释放资源
      reply->deleteLater();
      QCoreApplication::quit();
    });

    return a.exec();
}运行代码,读者可自行输入特定的网站进行读取测试,如下所示(完备代码请参考课件部分);
https://img2024.cnblogs.com/blog/1379525/202403/1379525-20240312125031896-457001706.png

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: C++ Qt开发:QNetworkAccessManager网络接口组件