Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Qt开源网络库[8]-上传文件与超时处理

Qt开源网络库[8]-上传文件与超时处理

作者头像
Qt君
发布于 2023-03-17 07:12:48
发布于 2023-03-17 07:12:48
1.7K00
代码可运行
举报
文章被收录于专栏:跟Qt君学编程跟Qt君学编程
运行总次数:0
代码可运行

重构了部分代码并在此基础上添加"上传文件"和"超时处理"的功能

一个简单的使用例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpClient client;
client.get("https://qthub.com")
      .onSuccess([](QString result) { qDebug()<<"result:"<<result; })
      .onFailed([](QString err) { qDebug()<<"error:"<<err; })
      .exec();

1. 如何使用?

  • 采用head-only的方式实现。只需在你的工程中包含 src 目录的 HttpClient.hpp 文件即可。
  • 源码地址在文末。

2. 使用文档

2.1 使用信号槽的方式实现成功与失败的事件处理

接口:

  • Http请求返回成功的信号槽绑定
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpRequest &onSuccess(const QObject *receiver, const char *method);
HttpRequest &onSuccess(std::function<void (QNetworkReply*)> lambda);
HttpRequest &onSuccess(std::function<void (QVariantMap)> lambda);
HttpRequest &onSuccess(std::function<void (QByteArray)> lambda);
  • Http请求返回失败的信号槽绑定
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpRequest &onFailed(const QObject *receiver, const char *method);
HttpRequest &onFailed(std::function<void (QString)> lambda);
HttpRequest &onFailed(std::function<void (QNetworkReply::NetworkError)> lambda);
HttpRequest &onFailed(std::function<void (QNetworkReply*)> lambda);

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static HttpClient client;
client.get("https://qthub.com")
      .onSuccess(this, SLOT(onSuccess(QString)))
      .onFailed(this, SLOT(onFailed(QString)))
      .exec(); // 执行Http操作

2.2 使用匿名函数的方式实现成功与失败的事件处理

接口:

  • Http请求返回成功的回调事件
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpRequest &onSuccess(std::function<void (QNetworkReply*)> lambda);
HttpRequest &onSuccess(std::function<void (QVariantMap)> lambda);
HttpRequest &onSuccess(std::function<void (QByteArray)> lambda);
  • Http请求返回失败的回调事件
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpRequest &onFailed(std::function<void (QString)> lambda);
HttpRequest &onFailed(std::function<void (QNetworkReply::NetworkError)> lambda);
HttpRequest &onFailed(std::function<void (QNetworkReply*)> lambda);

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
client.get("https://qthub.com")
      .onSuccess([](QString result) { qDebug()<<"result:"<<result.left(100); })
      .onFailed([](QString error) { qDebug()<<"error:"<<error; })
      .exec();

2.3 以信号槽的方式获取下载进度

接口:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpRequest &onDownloadProgress(const QObject *receiver, const char *method);

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
client.get("https://qthub.com")
      .onSuccess(this, SLOT(onSuccess(QString)))
      .onDownloadProgress(this, SLOT(onDownloadProgress(qint64, qint64)))
      .onFailed(this, SLOT(onFailed(QString)))
      .exec();

2.4 以匿名函数的方式获取下载进度

接口:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpRequest &onDownloadProgress(std::function<void (qint64, qint64)> lambda);

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
client.get("https://qthub.com")
      .onSuccess([](QString result) { qDebug()<<"result: " << result.left(10); })
      .onDownloadProgress([](qint64 bytesReceived, qint64 bytesTotal) {
          qDebug() << "lambda bytes received: " << bytesReceived
                   << "bytes total: " << bytesTotal;
       })
      .onFailed([](QString error) { qDebug()<<"error: " << error; })
      .exec();

2.5 post 上传文件并获取上传进度

接口:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpRequest &onUploadProgress(const QObject *receiver, const char *method);
HttpRequest &onUploadProgress(std::function<void (qint64, qint64)> lambda);

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
client.post("http://httpbin.org/post")
      .bodyWithFile("text_file", "helloworld.txt")
      .onUploadProgress([](qint64 bytesSent, qint64 bytesTotal) {
          qDebug() << "lambda bytes sent: " << bytesSent
                   << "bytes total: " << bytesTotal;
       })
      .onSuccess([](QString result) { qDebug()<<"result: " << result.left(100); })
      .onFailed([](QString error) { qDebug()<<"error: " << error; })
      .exec();

2.6 自定义超时时间和超时处理

  • timeout(ms)是设置超时时间,单位为毫秒(ms)。
  • onTimeout 为超时回调,当超时事件触发,自动调用 onTimeout 回调。

接口:

  • 设置超时时间
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpRequest &timeout(const int &msec = -1);
  • 设置超时的回调函数
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpRequest &onTimeout(const QObject *receiver, const char *method);
HttpRequest &onTimeout(std::function<void (QNetworkReply*)> lambda);
HttpRequest &onTimeout(std::function<void ()> lambda);

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
client.get("https://qthub.com")
      .onSuccess([](QString result) { qDebug()<<"result:"<<result.left(100); })
      .onFailed([](QString error) { qDebug()<<"error:"<<error; })
      .onTimeout([](QNetworkReply *) { qDebug()<<"timeout"; }) // 超时处理
      .timeout(1000) // 1s超时
      .exec();

2.7 由于 HttpClient 是异步实现,我们需要同步时可以这样做

接口:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpRequest &block();

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
client.get("https://qthub.com")
      .onSuccess(this, SLOT(onSuccess(QString)))
      .onFailed(this, SLOT(onFailed(QString)))
      .block() // 阻塞同步操作
      .exec(); // 执行Http操作

2.8 添加 header

接口:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpRequest &header(const QString &key, const QVariant &value);
HttpRequest &headers(const QMap<QString, QVariant> &headers);

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
client.post("https://example.com")
      .header("content-type", "application/json")
      .queryParam("key", "Hello world!")
      .body(R"({"user": "test"})")
      .onSuccess([](QString result){})
      .onFailed([](QString error){})
      .exec();

添加 params

接口:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpRequest &queryParam(const QString &key, const QVariant &value);
HttpRequest &queryParams(const QMap<QString, QVariant> &params);

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
client.get("https://example.com")
      .queryParam("key1", "value1")
      .queryParam("key2", "value2")
      .queryParam("key3", "value3")
      .onSuccess([](QString result){})
      .onFailed([](QString error){})
      .exec();

上面代码等同于:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
client.get("https://example.com?key1=value1&key2=value2&key3=value3")
      .onSuccess([](QString result){})
      .onFailed([](QString error){})

2.9 添加 body

接口:

  • 原始数据
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpRequest &body(const QByteArray &raw);
HttpRequest &bodyWithRaw(const QByteArray &raw);
  • json 数据
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpRequest &body(const QJsonObject &json);
HttpRequest &bodyWithJson(const QJsonObject &json);
  • 表单数据
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpRequest &body(const QVariantMap &formUrlencodedMap);
HttpRequest &bodyWithFormUrlencoded(const QVariantMap &keyValueMap);
  • 混合消息
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpRequest &body(QHttpMultiPart *multiPart);
HttpRequest &bodyWithMultiPart(QHttpMultiPart *multiPart);
  • 文件消息
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpRequest &body(const QString &key, const QString &file);
HttpRequest &bodyWithFile(const QString &key, const QString &file);
HttpRequest &bodyWithFile(const QMap<QString/*key*/, QString/*file*/> &fileMap);

例子:

发送原始数据
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
client.post("http://httpbin.org/post")
      .body("hello world")
      .onSuccess([](QString result){qDebug()<<result;})
      .onFailed([](QString error){qDebug()<<error;})
      .exec();
发送 json 数据
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QJsonObject json
{
    {"property1", 1},
    {"property2", 2}
};

client.post("http://httpbin.org/post")
      .body(json)
      .onSuccess([](QString result){qDebug()<<result;})
      .onFailed([](QString error){qDebug()<<error;})
      .exec();
发送表单数据
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QVariantMap map
{
    {"property1", 1},
    {"property2", 2}
};

client.post("http://httpbin.org/post")
      .body(map)
      .onSuccess([](QString result){qDebug()<<result;})
      .onFailed([](QString error){qDebug()<<error;})
      .exec();
发送混合消息
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);

    QFile *file = new QFile("demo.txt");
    file->open(QIODevice::ReadOnly);
    file->setParent(multiPart);

    QString dispositionHeader = QString("form-data; name=\"%1\";filename=\"%2\"")
            .arg("text_file")
            .arg(file->fileName());

    QHttpPart part;
    part.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/plain"));
    part.setHeader(QNetworkRequest::ContentDispositionHeader, dispositionHeader);
    part.setBodyDevice(file);

    multiPart->append(part);

    QString contentType = QString("multipart/form-data;boundary=%1").arg(multiPart->boundary().data());

HttpClient client;
client.post("http://httpbin.org/post")
      .header("content-type", contentType)
      .body(multiPart)
      .onSuccess([](QString result){ qDebug()<<result.left(1000); })
      .onFailed([](QString error){ qDebug()<<error; })
      .exec();
发送文件
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpClient client;
client.post("http://httpbin.org/post")
      .body("text_file", "demo.txt")
      .body("image_file", "demo.jpg")
      .onSuccess([](QString result){ qDebug()<<result.left(1000); })
      .onFailed([](QString error){ qDebug()<<error; })
      .exec();

2.10 携带特定的用户数据到响应回调函数

接口:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HttpRequest &userAttribute(const QVariant &value);

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
client.get("http://httpbin.org/get")
      .userAttribute("Hello world!")
      .onSuccess([](QNetworkReply *reply) {
            QVariant value = reply->request().attribute(QNetworkRequest::User);
            qDebug()<< value.toString();
       })
      .onFailed([](QString error){ qDebug()<<error; })
      .exec();

3. 源码地址

访问 https://github.com/aeagean/QtNetworkService

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Qt君 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Qt开源网络库[5]-lambda支持
在不断使用该库的过程中会遇到这样的一个问题,比如错误提示我只需要打印到终端就可以了,每一次的请求都需要定义一个槽函数然后等待异步调用.在这个过程中,需要定义一个槽函数就会略显得有些繁琐了.
Qt君
2019/07/15
1K0
Qt开源网络库[2]-接口篇
上一篇介绍了Qt开源网络库,有兴趣的可以翻开往期推送.今篇主要介绍该开源网络库接口的用法.
Qt君
2019/07/15
1.8K0
Qt开源网络库[9]-下载文件
有用户反馈说下载文件操作太麻烦了,想了想把这个功能加上吧。只需要简单地调用download()即可轻松下载文件。 接口: 设置下载操作。 /* 保存为默认的文件名,会从请求头去拿文件名字,如果请求头没有则为链接最后的文本内容。*/ HttpRequest &download(); /* 指定保存的文件名字,可包含路径。*/ HttpRequest &download(const QString &file); 响应回调/信号槽。 HttpRequest &onDownloadSuccess(const
Qt君
2023/03/17
9250
Qt开源网络库[9]-下载文件
Qt开源网络库[12]-身份验证
  当带有身份验证的请求时,我们需要填写用户名和密码等信息,但QNetworkAccessManager操作略显繁琐,所以特意封装了一下,简化用户操作。并在此基础上添加自动填写用户信息,验证次数限制和错误处理等功能。
Qt君
2023/03/17
1.1K0
Qt开源网络库[12]-身份验证
Qt开源网络库[7]-阻塞功能
有时候使用多个有顺序Http请求时(下一个请求需要上一个请求的内容),这时候阻塞功能非常有用。 接口 阻塞当前线程,并进入事件循环。 HttpRequest &block(); 实现 使用QEventLoop实现。 QEventLoop loop; QObject::connect(m_networkReply, SIGNAL(finished()), &loop, SLOT(quit())); loop.exec(); /* 阻塞当前线程,如在主线程不会冻结界面。*/ 示例 static HttpServ
Qt君
2019/11/06
1K0
Qt开源网络库[4]-原理篇下
上一篇分析到原理上,主要讲述的是builder模式设计与HttpService,HttpRequest的原理和实现。本篇将会讲到HttpResponse的响应机制与自动推导接收者(槽函数)的实现。
Qt君
2019/07/15
9950
Qt开源网络库[13]-断点续传下载
  默认开启断点续传下载功能,即当程序异常退出时,再次运行会接着从已下载的位置下载。   需要注意的是:如果服务器不支持断点续传功能,则每次下载都是从头开始下载。
Qt君
2023/03/17
5650
Qt开源网络库[13]-断点续传下载
Qt开源网络库[9]-失败重试与重复请求
实际项目使用中,出于对Http请求的容错性,多数都会采用请求失败后重试的策略。除新增了失败重试的功能外还提供重复请求的功能。 失败重试 接口:   设置失败请求后的重试次数,默认值为0。 HttpRequest &retry(int count);   重试次数执行完成后的信号槽/回调。 HttpRequest &onRetried(const QObject *receiver, const char *method); HttpRequest &onRetried(std::function<void
Qt君
2023/03/17
7890
Qt开源网络库[9]-失败重试与重复请求
Qt开源网络库[6]-超时功能
距离上一系列篇已经有半年没有更新了。本次介绍该网络库最近新增的超时功能(超时中断请求)。由于Qt的网络请求不能设置超时时间,故只能额外封装了。 接口 timeout通过msec参数设置超时时间; 当 msec<=0则禁用超时功能; 当 msec>0则使能超时功能,并将超时时间设置为 msec毫秒。 /** * @brief msec <= 0, disable timeout * msec > 0, enable timeout */ HttpRequest &timeout(cons
Qt君
2019/07/15
1.6K0
C++ Qt开发:QNetworkAccessManager网络接口组件
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用QNetworkAccessManager组件实现Web网页访问。
王瑞MVP
2024/03/12
8150
C++ Qt开发:QNetworkAccessManager网络接口组件
Qt开源网络库[3]-原理篇上
上一篇介绍到接口的使用,本篇主要讲述的是该网络库的HttpService与HttpRequest原理与实现。对QNetworkAccessManager封装和管理Http请求。采用builder设计模式,这样在多参数情况下可以灵活运用。
Qt君
2019/07/15
1.4K0
QT应用编程: 基于UDP协议设计的大文件传输软件
功能介绍: 软件由客户端和服务器组成,客户端通过 UDP协议不断循环地向服务端发送文件,文件传输速率可以达到10MB/s以上,文件传输后支持自动删除,客户端上可以支持每分钟创建一个文件并以时间戳命名,每个生成的文件可以设置大小,默认大小为6GB; 服务端收到文件之后,将文件进行存储到本地,可以指定时间自动删除文件; 服务端可以动态计算传输速率,并写入日志文件; 服务器可以支持同时接收多个客户端的文件上传。
DS小龙哥
2022/01/07
3K0
QT应用编程: 基于UDP协议设计的大文件传输软件
Qt学习笔记网络(一)
Qt5 移除了QHttp是因为功能重复 用QNetworkAccessManager完全能搞定 新建一个控制台应用程序 看一下QNetworkAccessManager的帮助文档 需要添加Qt + =
lpxxn
2018/01/31
1.1K0
Qt学习笔记网络(一)
100行代码开源翻译小工具
  100行代码实现翻译小工具,支持中英互译。程序执行文件就不发布了,有兴趣可以下载源码自己编译运行。
Qt君
2023/11/26
4610
100行代码开源翻译小工具
QT软件开发:基于QtAV设计的视频播放器
完整源码下载: https://download.csdn.net/download/xiaolong1126626497/19759245
DS小龙哥
2022/01/12
1.8K0
QT软件开发:基于QtAV设计的视频播放器
QT应用编程:基于QMediaPlayer开发音视频播放器
QMediaPlayer是Qt提供的一个跨平台媒体播放器类,它没有自带解码库,而是对平台相关的播放器框架做了封装,提供了平台无关的API。所以使用QMediaPlayer播放视频,需要提前安装解码库。 在win系统下可以下载K-Lite_Codec_Pack或者LAVFilters解码库安装。
DS小龙哥
2022/01/07
3.7K0
QT应用编程:基于QMediaPlayer开发音视频播放器
基于Qt的网络音乐播放器(四)酷狗API接口获取歌曲的搜索列表和歌曲的播放
如果有一天,这个代码不能用了,要注意查询的值对不对,酷狗可能是为了防止被爬,data,info,等等这些值有可能被更换成别的,要观察json。
花狗Fdog
2020/10/28
3.3K0
基于Qt的网络音乐播放器(四)酷狗API接口获取歌曲的搜索列表和歌曲的播放
Qt 学习之路 2(64):使用 QJsonDocument 处理 JSON
本文转载自豆子的Qt 学习之路2的博客Qt 学习之路 2(64):使用 QJsonDocument 处理 JSON
ccf19881030
2021/04/19
5.3K0
Qt 学习之路 2(64):使用 QJsonDocument 处理 JSON
Qt 教程二
因为Qt是一个C++框架, 因此C++中所有的语法和数据类型在Qt中都是被支持的, 但是Qt中也定义了一些属于自己的数据类型, 下边给大家介绍一下这些基础的数类型。
用户11332765
2024/10/28
7980
基于Qt的UDP通信、TCP文件传输程序的设计与实现——QQ聊天群聊
QQ是一款优秀的聊天软件,本文将提供主要代码和思路来实现一个类似于QQ群聊的网络聊天软件,大致有以下俩个功能:
秋名山码神
2023/11/23
1.1K0
基于Qt的UDP通信、TCP文件传输程序的设计与实现——QQ聊天群聊
推荐阅读
相关推荐
Qt开源网络库[5]-lambda支持
更多 >
LV.0
这个人很懒,什么都没有留下~
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验