Qt扫盲-QNetworkAccessManager理论总结

一、概述

QNetworkAccessManager 其实就是一个访问网络接口的管理工具类,该对象保存了它发送的请求的公共配置和设置(其实就是 QNetworkRequest 里的配置数据)。它包含代理和缓存配置,以及与此类问题相关的信号,以及可用于监视网络操作进展的应答信号,也就是下载进度、上传进度等信号。

一个QNetworkAccessManager实例对整个Qt应用程序来说就足够了。由于QNetworkAccessManager是基于QObject的,它只能从它所属的线程使用。

一旦创建了QNetworkAccessManager对象,应用程序就可以使用它通过网络发送请求。它提供了一组标准函数,接收一个请求和可选的数据,每个函数返回一个QNetworkReply对象。返回对象用于获取响应相应请求而返回的任何数据。

二、基础用法

1. 下载数据

通过以下的基本方式可以完成一个简单的网络下载:

使用的即是 get() 方法,这个就是只下载而不会回上传数据到服务器之类的,上传服务器即是要用 post() 方法

QNetworkAccessManager *manager = new QNetworkAccessManager(this);

//因为是发送请求到接收到数据是异步的,replyFinished 就是处理请求完成后的槽函数
connect(manager, &QNetworkAccessManager::finished,
          this, &MyClass::replyFinished);

//通过请求获取到数据
manager->get(QNetworkRequest(QUrl("http://qt-project.org")));

QNetworkAccessManager有一个异步API。当上面的replyFinished槽函数被调用时,它接受的参数是QNetworkReply对象,其中包含下载的数据以及元数据(首部等)。 这个get 方法只是下载

  • 注意:请求完成后,用户有责任在适当的时间删除QNetworkReply对象。不要在连接到finished()的槽内直接删除它。可以使用deleteLater()函数。
  • 注意:QNetworkAccessManager对它接收到的请求进行队列。并行执行的请求数量取决于协议。目前,对于桌面平台上的HTTP协议,一个主机/端口组合并行执行6个请求。

假设manager已经存在,下面是一个更复杂的例子:

  QNetworkRequest request;
  request.setUrl(QUrl("http://qt-project.org"));
  request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");

  QNetworkReply *reply = manager->get(request);
  connect(reply, &QIODevice::readyRead, this, &MyClass::slotReadyRead);
  connect(reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
          this, &MyClass::slotError);
  connect(reply, &QNetworkReply::sslErrors,
          this, &MyClass::slotSslErrors);

2. 上传数据

当然还可以使用 post(const QNetworkRequest &request, QIODevice *data) 方法 发送请求和数据

  • post() 函数介绍:向request指定的目的地发送一个HTTP POST请求,并返回一个新的QNetworkReply对象,该对象打开以供读取,其中将包含服务器发送的应答。数据设备的内容将被上传到服务器。
    数据必须打开以便读取,并且必须在finished()信号发出之前保持有效。

下面就是一个 上传数据到服务器的一个简单例子,QHttpMultiPart 其实就是上传MIME 数据的盒子,这个也就是上传附件之类的函数。下面就是上传一张图片和一段文本的样例。

  QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);

  QHttpPart textPart;
  textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"text\""));
  textPart.setBody("my text");

  QHttpPart imagePart;
  imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));
  imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image\""));
  QFile *file = new QFile("image.jpg");
  file->open(QIODevice::ReadOnly);
  imagePart.setBodyDevice(file);
  file->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart

  multiPart->append(textPart);
  multiPart->append(imagePart);

  QUrl url("http://my.server.tld");
  QNetworkRequest request(url);

  QNetworkAccessManager manager;
  QNetworkReply *reply = manager.post(request, multiPart);
  multiPart->setParent(reply); // delete the multiPart with the reply
  // here connect signals etc.

同样还有就是用的 head() 方法,这个就是只交换头部数据,而不会传输body ,这个也是http协议的一部分。

二、网络和漫游支持

这个我用的很少,我暂时不太清楚。

随着Qt 4.7的承载管理API的增加,QNetworkAccessManager获得了管理网络连接的能力。如果设备离线,QNetworkAccessManager可以启动网络接口,如果当前进程是最后一个使用上行链路的进程,则终止该接口。请注意,有些平台从最后一个应用程序停止使用上行链路开始,一直到系统实际终止连接链路为止,都会使用宽限期。漫游同样透明。任何排队/待处理的网络请求都会自动转移到新的访问点。
想要利用这个特性的客户端不需要任何更改。事实上,很可能现有的特定于平台的连接代码可以简单地从应用程序中删除。
注意:QNetworkAccessManager的网络和漫游支持取决于支持连接管理的平台。QNetworkConfigurationManager::NetworkSessionRequired可用于检测QNetworkAccessManager是否利用此功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

太阳风暴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值