一、说明

QT5拥有强大网络能力,本篇专门展示QT5如何实现网上下载;本篇讲相关类、以及配套的类:

  • QNetworkAccessManager
  • QVector <QString> stringVector;
  • QNetworkReply
  • QNetworkRequest request;

二、类详细解释

2.1 网络连接

互联网上的请求-应答如下:

 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, &QNetworkReply::errorOccurred,this, &MyClass::slotError);connect(reply, &QNetworkReply::sslErrors,this, &MyClass::slotSslErrors);

2.2 最简单下载语句

QNetworkAccessManager *manager = new QNetworkAccessManager(this);connect(manager, &QNetworkAccessManager::finished, this, &MyClass::replyFinished);manager->get(QNetworkRequest(QUrl("http://qt-project.org")));

三、QNetworkAccessManager成员

3.1 类型成员

1、enum QNetworkAccessManager::Operation:指示回复正在处理的操作。

HeadOperation:检索headers操作(使用 head() 创建)
GetOperation:检索headers和下载内容(使用 get() 创建)
PutOperation:上传内容操作(使用 put() 创建)
PostOperation:发送 HTML 表单的内容以通过 HTTP POST 进行处理(使用 post() 创建)
DeleteOperation:删除内容操作(使用 deleteResource() 创建)
CustomOperation:自定义操作(使用 sendCustomRequest() 创建)

3.2 成员函数

1、[signal] void authenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator)

每当服务器在交付请求的内容之前请求身份验证时,都会发出此信号。连接到此信号的槽函数应填充验证器对象中的凭据。

QNetworkAccessManager 将在内部缓存凭据,如果服务器再次需要身份验证,则将发送相同的值,而不发出此信号。如果服务器拒绝凭据,将再次发出此信号。

注意:无法使用 QueuedConnection 连接到此信号,因为如果在信号返回时验证器未填充新信息,则连接将失败。

2、[signal] void encrypted(QNetworkReply *reply)

当 SSL/TLS 会话成功完成初始握手时,会发出此信号。此时,还没有传输用户数据。

3、[signal] void finished(QNetworkReply *reply)

网络回复完成时会发出此信号。回复参数将包含一个指向刚刚完成的回复的指针。该信号与 QNetworkReply::finished() 信号一起发出。

注意:不要直接删除连接到该信号的槽中的回复对象。应使用 deleteLater()。

4、[signal] void preSharedKeyAuthenticationRequired(QNetworkReply *reply, QSslPreSharedKeyAuthenticator *authenticator)

如果 SSL/TLS 握手协商 PSK 密码套件,则会发出此信号,因此需要 PSK 身份验证。 回复对象是正在协商此类密码套件的 QNetworkReply。

使用 PSK 时,客户端必须向服务器发送一个有效的身份和一个有效的预共享密钥,以便 SSL 握手继续进行。 应用程序可以在连接到这个信号的槽中提供这个信息,根据他们的需要填充传递的验证器对象。

注意:忽略此信号,或未能提供所需的凭据,将导致握手失败,从而中止连接。

注意:验证器对象归回复所有,不得被应用程序删除。

5、[signal] void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)

每当代理请求身份验证并且 QNetworkAccessManager 找不到有效的缓存凭据时,就会发出此信号。连接到此信号的槽函数应填写身份验证器对象中的代理凭据。

QNetworkAccessManager 将在内部缓存凭据。下次代理请求身份验证时,将自动发送相同的凭据,而不会再次发出此信号。

如果代理拒绝凭据,QNetworkAccessManager 将再次发出信号。

6、[signal] void sslErrors(QNetworkReply *reply, const QList<QSslError> &errors)

如果 SSL/TLS 会话在设置期间遇到错误,包括证书验证错误,则会发出此信号。 errors 参数包含错误列表,reply 是遇到这些错误的 QNetworkReply。

为了表明错误不是致命的并且连接应该继续,应该从连接到这个信号的槽函数调用 QNetworkReply::ignoreSslErrors() 函数。如果未调用 SSL 会话将断开。

此信号可用于向用户显示错误消息,指示安全性可能受到威胁并显示 SSL 设置。如果用户在分析远程证书后决定继续,则槽函数应调用 ignoreSslErrors()。

7、void addStrictTransportSecurityHosts(const QVector<QHstsPolicy> &knownHosts)

将 HTTP 严格传输安全策略添加到 HSTS 缓存中。

8、void clearAccessCache()

刷新身份验证数据和网络连接的内部缓存。

9、void clearConnectionCache()

刷新网络连接的内部缓存。与 clearAccessCache() 相比,身份验证数据被保留。

10、void connectToHost(const QString &hostName, quint16 port = 80)

与指定的主机连接。

11、void connectToHostEncrypted(const QString &hostName, quint16 port = 443, const QSslConfiguration &sslConfiguration = QSslConfiguration::defaultConfiguration())

使用 sslConfiguration 配置与指定的主机连接。

12、void connectToHostEncrypted(const QString &hostName, quint16 port, const QSslConfiguration &sslConfiguration, const QString &peerName)

重载函数。使用 sslConfiguration 配置与指定的主机连接,peerName为用于证书验证的主机名。

13、QNetworkReply *deleteResource(const QNetworkRequest &request)

发送请求以删除由请求的 URL 标识的资源。此功能目前仅适用于 HTTP,执行 HTTP DELETE 请求。

14、QNetworkReply * get(const QNetworkRequest &request)

发布请求以获取内容,返回一个新的 QNetworkReply 对象,该对象在新数据到达时发出 readyRead() 信号。

15、QNetworkReply * head(const QNetworkRequest &request)

发布请求以获取请求的网络标头并返回一个新的 QNetworkReply 对象。

16、QNetworkReply * post(const QNetworkRequest &request, QIODevice *data)

将 HTTP POST 请求发送到 request 指定的目的地,并返回一个新的 QNetworkReply 对象,该对象将包含服务器发送的回复。data的内容将上传到服务器。

data必须打开以供读取,并且必须保持有效,直到为此回复发出finished()信号。

注意:在 HTTP 和 HTTPS 以外的协议上发送 POST 请求是未定义的,并且可能会失败。

17、QNetworkReply * post(const QNetworkRequest &request, const QByteArray &data)

重载函数。将数据字节数组的内容发送到请求指定的目的地。

18、QNetworkReply * post(const QNetworkRequest &request, QHttpMultiPart *multiPart)

重载函数。将 HTTP multipart MIME 消息的内容发送到请求指定的目的地。

19、QNetworkReply * put(const QNetworkRequest &request, QIODevice *data)

将数据上传到request设置的目标并返回一个新的 QNetworkReply 对象。

调用此函数时,必须打开(QIODevice::open())设备以进行读取,并且必须保持有效,直到为此回复发出finished() 信号为止。

20、QNetworkReply * put(const QNetworkRequest &request, const QByteArray &data)

21、QNetworkReply * put(const QNetworkRequest &request, QHttpMultiPart *multiPart)

重载函数。

22、QNetworkReply * sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data = nullptr)

向由请求的 URL 标识的服务器发送自定义请求。

用户有责任将根据 HTTP 规范有效的动词发送到服务器。

此方法提供了发送除通过 get() 或 post() 等提供的常用动词以外的动词的方法,例如发送 HTTP OPTIONS 命令。

如果数据不为空,则将数据设备的内容上传到服务器; 在这种情况下,必须打开(QIODevice::open())设备以进行读取,并且必须保持有效,直到为此回复发出finished() 信号为止。

23、QNetworkReply * sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, const QByteArray &data)

24、QNetworkReply * sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QHttpMultiPart *multiPart)

重载函数。

25、void setAutoDeleteReplies(bool shouldAutoDelete)

启用或禁用 QNetworkReply 的自动删除。设置为 true 与将 QNetworkRequest::AutoDeleteReplyOnFinishAttribute 属性设置为 true 相同。

26、void setCache(QAbstractNetworkCache *cache)

设置网络缓存对象。

27、void setCookieJar(QNetworkCookieJar *cookieJar)

设置保存cookie的对象。

28、void setProxy(const QNetworkProxy &proxy)

设置代理。

29、void setProxyFactory(QNetworkProxyFactory *factory)

设置代理工厂。代理工厂用于具体的代理列表,而不是尝试对所有请求使用相同的代理值(即根据不同情况使用不同的代理)。QNetworkAccessManager 发送的所有查询都将具有 QNetworkProxyQuery::UrlRequest 类型。

例如,代理工厂可以应用以下规则:

如果目标地址在本地网络中,则返回 QNetworkProxy::NoProxy
如果请求是 FTP,则返回一个 FTP 代理
如果请求是 HTTP 或 HTTPS,则返回 HTTP 代理
其他情况返回 SOCKSv5 代理服务器
如果使用 setProxy() 设置了特定代理,则不会使用工厂。

30、void setRedirectPolicy(QNetworkRequest::RedirectPolicy policy)

设置重定向策略。

31、void setStrictTransportSecurityEnabled(bool enabled)

设置是否遵循 HTTP 严格传输安全策略(HSTS,RFC6797)。

如果启用:

处理请求时,QNetworkAccessManager 会自动将“http”方案替换为“https”,并为 HSTS 主机使用安全传输。如果明确设置,则端口 80 将替换为端口 443。
对于每个包含 HSTS 标头并通过安全传输接收的 HTTP 响应,QNetworkAccessManager 将更新其 HSTS 缓存,或者记住具有有效策略的主机或删除具有过期或禁用 HSTS 策略的主机。
32、void setTransferTimeout(int timeout = QNetworkRequest::DefaultTransferTimeoutConstant)

设置传输超时时间。如果在超时到期之前没有传输字节,传输将被中止。

零表示未设置计时器。如果未调用此函数,则超时将被禁用且值为 0。

33、QVector<QHstsPolicy> strictTransportSecurityHosts()

返回 HTTP 严格传输安全策略列表。如果 HSTS 缓存是从“Strict-Transport-Security”响应标头更新的,则此列表可能与最初通过 addStrictTransportSecurityHosts() 设置的不同。

34、QStringList supportedSchemes()

列出支持的所有 URL 方案。

3.3 示例代码

#include <QtCore>
#include <QtNetwork>#include <cstdio>QT_BEGIN_NAMESPACE
class QSslError;
QT_END_NAMESPACEusing namespace std;class DownloadManager: public QObject
{Q_OBJECTQNetworkAccessManager manager;QVector<QNetworkReply *> currentDownloads;public:DownloadManager();void doDownload(const QUrl &url);static QString saveFileName(const QUrl &url);bool saveToDisk(const QString &filename, QIODevice *data);static bool isHttpRedirect(QNetworkReply *reply);public slots:void execute();void downloadFinished(QNetworkReply *reply);void sslErrors(const QList<QSslError> &errors);
};DownloadManager::DownloadManager()
{connect(&manager, &QNetworkAccessManager::finished,this, &DownloadManager::downloadFinished);
}void DownloadManager::doDownload(const QUrl &url)
{QNetworkRequest request(url);QNetworkReply *reply = manager.get(request);#if QT_CONFIG(ssl)connect(reply, &QNetworkReply::sslErrors,this, &DownloadManager::sslErrors);
#endifcurrentDownloads.append(reply);
}QString DownloadManager::saveFileName(const QUrl &url)
{QString path = url.path();QString basename = QFileInfo(path).fileName();if (basename.isEmpty())basename = "download";if (QFile::exists(basename)) {// already exists, don't overwriteint i = 0;basename += '.';while (QFile::exists(basename + QString::number(i)))++i;basename += QString::number(i);}return basename;
}bool DownloadManager::saveToDisk(const QString &filename, QIODevice *data)
{QFile file(filename);if (!file.open(QIODevice::WriteOnly)) {fprintf(stderr, "Could not open %s for writing: %s\n",qPrintable(filename),qPrintable(file.errorString()));return false;}file.write(data->readAll());file.close();return true;
}bool DownloadManager::isHttpRedirect(QNetworkReply *reply)
{int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();return statusCode == 301 || statusCode == 302 || statusCode == 303|| statusCode == 305 || statusCode == 307 || statusCode == 308;
}void DownloadManager::execute()
{QStringList args = QCoreApplication::instance()->arguments();args.takeFirst();           // skip the first argument, which is the program's nameif (args.isEmpty()) {printf("Qt Download example - downloads all URLs in parallel\n""Usage: download url1 [url2... urlN]\n""\n""Downloads the URLs passed in the command-line to the local directory\n""If the target file already exists, a .0, .1, .2, etc. is appended to\n""differentiate.\n");QCoreApplication::instance()->quit();return;}for (const QString &arg : qAsConst(args)) {QUrl url = QUrl::fromEncoded(arg.toLocal8Bit());doDownload(url);}
}void DownloadManager::sslErrors(const QList<QSslError> &sslErrors)
{
#if QT_CONFIG(ssl)for (const QSslError &error : sslErrors)fprintf(stderr, "SSL error: %s\n", qPrintable(error.errorString()));
#elseQ_UNUSED(sslErrors);
#endif
}void DownloadManager::downloadFinished(QNetworkReply *reply)
{QUrl url = reply->url();if (reply->error()) {fprintf(stderr, "Download of %s failed: %s\n",url.toEncoded().constData(),qPrintable(reply->errorString()));} else {if (isHttpRedirect(reply)) {fputs("Request was redirected.\n", stderr);} else {QString filename = saveFileName(url);if (saveToDisk(filename, reply)) {printf("Download of %s succeeded (saved to %s)\n",url.toEncoded().constData(), qPrintable(filename));}}}currentDownloads.removeAll(reply);reply->deleteLater();if (currentDownloads.isEmpty()) {// all downloads finishedQCoreApplication::instance()->quit();}
}int main(int argc, char **argv)
{QCoreApplication app(argc, argv);DownloadManager manager;QTimer::singleShot(0, &manager, SLOT(execute()));app.exec();
}#include "main.moc"

QT5知识:网上下载相关推荐

  1. 用CMake编译运行在网上下载的源文件src

    参考:http://blog.csdn.net/yiqiudream/article/details/51885698 (一).怎么用CMake打开下载的源文件? 工具:下载CMake --> ...

  2. java 文件下载详解_Java 从网上下载文件的几种方式实例代码详解

    废话不多说了,直接给大家贴代码了,具体代码如下所示: package com.github.pandafang.tool; import java.io.BufferedOutputStream; i ...

  3. android 服务端 导入工程,如何导入与配置从网上下载的android源代码及服务器端源代码...

    将Android项目导入import进Eclipse. 注意SDK版本是否匹配 . 服务器部署到Tomcat下. 你得在数据库中将这个点菜系统的数据库和表建好,或者导入.在服务器的代码中修改好你的数据 ...

  4. 如何把网上下载的前端页面在Spring Boot中跑起来(CSS,JavaScript,程序运行等路径设置)

    这个功能非常有用,估计99.99%的java web开发者都干过,本人是初学者,特写这个博客记录下! 方便本人以后查阅,方便以后进行投机取巧 这里使用thymeleaf模板引擎! 在网上下载了一个Bo ...

  5. 自己封装的Windows7 64位旗舰版,微软官网上下载的Windows7原版镜像制作,绝对纯净版...

    MSDN官网上下载的Windows7 64位 旗舰版原版镜像制作,绝对纯净版,无任何精简,不捆绑任何第三方软件.浏览器插件,不含任何木马.病毒等. 集成: 1.Office2010 2.DirectX ...

  6. 在spring官网上下载历史版本的spring插件,springsource-tool-suite

    在spring官网上下载历史版本的spring插件,springsource-tool-suite 如何为自己的eclipse下载历史版本的sts呢?拼下载的url. 首先,鼠标右键可下载的sts链接 ...

  7. 解决 网上下载的例子 My Mac 64-bit 不能运行的问题

    在左侧选中项目名称,在右侧TARGETS中选择  Summary , 将Deployment Target 字段改成你本机能够支持的版本.例如此次我从网上下载的例子是基于6.0开发的,那么我将其改为5 ...

  8. 生成网上下载的EF项目对应的数据库

    网上下载的用EF做的小项目,结果没有配有数据库的,用VS打开来看了一下,看到Migrations文件夹,应该可以用EF命令来生成这个数据库了 打开appsettings.json文件,可以看到他用了三 ...

  9. 使用wget从网上下载ubuntu源到互联网硬盘,拿到内部用

    背景:内部工作机不方便连接互联网更新ubuntu源,需要拿一块全新或者互联网硬盘从互联网下载源,然后拿到内部机使用,避免内部机接触互联网. 从网上下载Ubuntu源的工具:wget wget下载地址: ...

最新文章

  1. TCP/IP 协议理解
  2. 再来一个吊打百度网盘的开源神器,还是99年妹子开发的
  3. 使用Eclipse 创建 搭建SpringBoot项目
  4. ubuntu开发c/c++帮助文档
  5. 本地管理表空间(LMT)
  6. java注册机软件_myeclipse 8.5 注册机
  7. 数据结构导论【五】之 图
  8. 动词过去式和过去分词不规则变化
  9. 置换检验 配对秩和检验
  10. c语言程序设计张新成课后习题答案,C语言练习题2
  11. 边境的悍匪—机器学习实战:第八章 降维
  12. ceph 集群报 mds cluster is degraded 故障排查
  13. 今天来和大家一起分享一下好玩的游戏---美国农场主
  14. KVM虚拟机如何新增一块磁盘?
  15. This must be due to duplicate classes or playing wrongly with class loaders 1
  16. MySQL学习之路(一):使用命令行登录mysql的方式
  17. 工作多年,我对架构的一些理解
  18. 05.Laravel post提交失败 返419 | Page Expired
  19. 邪恶心理学-真实面对谎言的本质
  20. vc++经典技巧总结

热门文章

  1. Linux 中卷组不真实存在情况下,强制删除卷组及其PV信息
  2. MATLAB碎纸片的拼接复原
  3. 缺陷的定义级别、优先级及状态
  4. 计算机主机发出滴滴声音,为什么Win7电脑总是发出滴滴滴声?出现的原因及解决方法...
  5. 计算机滴滴响重启,刚刚电脑滴滴的响一开始有节奏的响,后面就滴滴滴的一直响了几分钟,然后自动关机重启了,是怎么回事?!...
  6. PHP 异常错误处理
  7. oj水题,求平均成绩
  8. 快速将桌面文件转移别的盘
  9. 利用blender+Open Street Map+blender-geo制作3D地图渲染图
  10. 量子计算机编程pdf,量子计算与量子计算机.pdf