Qt http

文章目录

  • 前言
    • 1. 定义的接口
    • 2.connect信号槽
    • 3. get
    • 4. get 下载文件
    • 5. post
  • 总结


前言

/*
1.请求报文:
请求报文是由客户端发送给服务器,用于请求特定资源或执行特定操作。它由以下几个部分组成:
请求行:描述了请求的方法、目标资源的路径和HTTP协议的版本,通常包含以下三个字段:

        请求方法:指定了客户端希望服务器执行的操作,如GET、POST、PUT、DELETE等。
请求目标:表示客户端希望访问的资源路径,可以是绝对路径或相对路径。协议版本:指定所使用的HTTP协议的版本,如HTTP/1.1。
请求头:包含了关于请求的附加信息,格式为键值对。常见的请求头字段包括:Host:指定请求的目标主机。
User-Agent:标识发送请求的客户端应用程序。
Content-Type:指定请求正文的类型。
请求正文(可选):包含客户端发送给服务器的数据,通常在使用POST等方法时使用。

2.响应报文:
响应报文是服务器对客户端请求的回应,包含了所请求资源的数据或执行结果。它由以下几个部分组成:
状态行:描述了响应的状态,包含以下三个字段:

协议版本:指定所使用的HTTP协议的版本,如HTTP/1.1。
状态码:表示服务器对请求的处理结果,如200表示成功,404表示资源未找到。
状态信息:对状态码进行简短的解释说明。
响应头:包含了关于响应的附加信息,格式为键值对。常见的响应头字段包括:Content-Type:指定响应正文的类型。
Content-Length:指定响应正文的长度。
Set-Cookie:在响应中设置Cookie。
响应正文:包含了服务器返回给客户端的数据,可以是HTML、JSON、文件等。请求报文和响应报文的结构化文本格式使得客户端和服务器能够互相理解并进行有效的通信。
它们是HTTP通信的基础,用于传递请求和响应的相关信息******************************************************
text/html 表示数据格式是 HTML
text/css 表示数据格式是 CSS
application/javascript 表示数据各式是 JavaScript
application/json 表示数据格式是 JSON
******************************************************

*/


1. 定义的接口

  1. public公共接口,用作单线程
  2. public slots公共槽函数,支持类对象调用,在哪个线程调用即在哪个线程运行
  3. signals 信号,通过调用信号的方式在其对应槽函数线程创建事件执行,用于多线程
public:bool get(QString url, QString &data, int timeout = 20000);bool post(QString url, QString &data, QByteArray jsonData, int timeout = 20000);bool getDownload(QString url, QString filePath, int timeout = 20000);signals:void sgnGet(QString url, int timeout = 20000);void sgnPost(QString url,QByteArray jsonData, int timeout = 20000);void sgnGetDownload(QString url, QString filePath, int timeout = 20000);void Progress(qint64, qint64);void finished(QString data, bool result);public slots:void gets(QString url, int timeout = 20000);void posts(QString url,QByteArray jsonData, int timeout = 20000);void getDownloads(QString url, QString filePath, int timeout = 20000);

2.connect信号槽

    connect(this, &Http::sgnGet, this, &Http::gets);connect(this, &Http::sgnGetDownload, this, &Http::getDownloads);connect(this, &Http::sgnPost, this, &Http::posts);

3. get

//! 通过信号槽的方式调动
void Http::gets(QString url, int timeout)
{QString data = "";bool rt = this->get(url, data, timeout);emit finished(data, rt);
}
//! get请求数据
bool Http::get(QString url, QString& data, int timeout)
{qDebug()<<"Http       QThread::currentThread() = "<<QThread::currentThread();int repeatSend = 0;// 三次请求失败结束请求数据while(!repeatGet(url, data, timeout)){if(++repeatSend >= 3) return false;}return true;
}
//!
bool Http::repeatGet(QString& url, QString& data, int& timeout)
{// 建立事件循环QEventLoop loop;//设置发送请求所需的信息QNetworkRequest request;request.setUrl(QUrl(url));request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded"));//管理网络请求和响应QNetworkAccessManager manager;connect(&manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit);// 超时检测QTimer timer;timer.setSingleShot(true);connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);// 处理网络请求的响应数据QNetworkReply* pReply = manager.get(request);connect(pReply, &QNetworkReply::finished, &loop, &QEventLoop::quit);connect(pReply, SIGNAL(error(QNetworkReply::NetworkError)), &loop, SLOT(quit()));// 超时检测定时器启动timer.start((timeout > 0) ? timeout : 2000);//执行事件循环,直到退出循环再执行后面代码loop.exec();//! 退出事件循环,判断定时器是否触发,触发即超时if(!timer.isActive()){pReply->deleteLater();return false;}//! 未超时停止定时器timer.stop();//QNetworkReply::NetworkError err = pReply->error();if(err != QNetworkReply::NoError){// 检测状态码int statusCode  = pReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();qDebug()<<"get error, statusCode = "<<statusCode;return false;}//data = QString::fromUtf8(pReply->readAll());pReply->deleteLater();return true;
}

执行代码:

QString data = "";
qDebug()<<"----------------------------------";
qDebug()<< "MainWindow QThread::currentThread() = "<< QThread::currentThread();
qDebug()<<data.size();
data.clear();
qDebug()<<"--------------- 1 ----------------";
http->get(QString("http://www.baidu.com"),data, 2000);
qDebug()<<data.size();
data.clear();
qDebug()<<"--------------- 2 ----------------";
http->gets(QString("http://www.baidu.com"), 2000);
qDebug()<<data.size();
data.clear();
qDebug()<<"--------------- 3 ----------------";
emit http->sgnGet(QString("http://www.baidu.com"), 2000);
qDebug()<<data.size();
qDebug()<<"----------------------------------";
// 保存HTTP响应内容
// 组装保存的文件名 文件名格式: 路径/年_月_日 小时_分_秒 httpfile.html
QDateTime current_date_time =QDateTime::currentDateTime();
QString current_date =current_date_time.toString("yyyy_MM_dd hh_mm_ss");
QString filePath = ".";
QString fileName = filePath + '/' + current_date + " httpfile" + ".html";QFile file(fileName);
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)){//qDebug() << "file open error!";return ;
}
QTextStream out(&file);
out.setCodec("UTF-8");
out<<data;
file.close();
data.clear();

通过信号槽是多线程且异步的

在这里插入图片描述

4. get 下载文件

void Http::getDownloads(QString url, QString filePath, int timeout)
{bool rt = this->getDownload(url, filePath, timeout);emit finished(filePath, rt);
}
bool Http::getDownload(QString url, QString filePath, int timeout)
{qDebug()<<"Http        QThread::currentThread() = "<<QThread::currentThread();int repeatSend = 0;//while(!repeatGetDownload(url, filePath, timeout)){if(++repeatSend >= 3) return false;}return true;
}
bool Http::repeatGetDownload(QString& url, const QString& filePath, const int& timeout)
{if(!pFile.isOpen()) pFile.setFileName(filePath);//QEventLoop loop;//QNetworkRequest request;request.setUrl(QUrl(url));//QNetworkAccessManager manager;connect(&manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit);//QTimer timer;timer.setSingleShot(true);connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);//QNetworkReply* pReply = manager.get(request);connect(pReply, &QNetworkReply::finished, &loop, &QEventLoop::quit);connect(pReply, SIGNAL(error(QNetworkReply::NetworkError)), &loop, SLOT(quit()));connect(pReply, &QNetworkReply::readyRead, &loop, &QEventLoop::quit);//timer.start((timeout > 0) ? timeout : 20000);loop.exec(QEventLoop::ExcludeSocketNotifiers);disconnect(pReply, &QNetworkReply::readyRead, &loop, &QEventLoop::quit);//! 超时if(!timer.isActive()){pReply->deleteLater();return false;}else{timer.stop();}QNetworkReply::NetworkError err = pReply->error();if(err != QNetworkReply::NoError){// 检测状态码int statusCode  = pReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();qDebug()<<"get error, statusCode = "<<statusCode;//! 重定向const QVariant redirectionTarget = pReply->attribute(QNetworkRequest::RedirectionTargetAttribute);if(!redirectionTarget.isNull()){QUrl redirectedUrl = redirectionTarget.toUrl();url = redirectedUrl.toString();}return false;}connect(pReply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(LoadProgress(qint64,qint64)));connect(pReply, &QNetworkReply::readyRead, this, &Http::readSave);loop.exec();return true;
}
void Http::readSave()
{QNetworkReply* pReply = (QNetworkReply*)sender();if(!pFile.isOpen()){//! save fileif(!pFile.open(QIODevice::WriteOnly)){qDebug() << pFile.errorString();}}pFile.write(pReply->readAll());
}
void Http::LoadProgress(qint64 recved, qint64 total)
{QNetworkReply* pReply = (QNetworkReply*)sender();if(recved >= total){pFile.close();pReply->deleteLater();}
}

执行代码

QString url = "https://1.as.dl.wireshark.org/win64/Wireshark-win64-4.0.10.exe";
url = "https://enigmaprotector.com/assets/files/enigma_en_demo.exe";qDebug()<<"----------------------------------";
qDebug()<< "MainWindow QThread::currentThread() = "<< QThread::currentThread();
qDebug()<<"--------------- 1 ----------------";
QString path = "./enigma1.exe";
//http->getDownload(url, path, 4000);
qDebug()<<"--------------- 2 ----------------";
path = "./enigma2.exe";
//http->getDownloads(url, path, 4000);
qDebug()<<"--------------- 3 ----------------";
path = "./enigma3.exe";
emit http->sgnGetDownload(url, path, 4000);
qDebug()<<"----------------------------------";

在这里插入图片描述

5. post

没测试过

void Http::posts(QString url,QByteArray jsonData, int timeout)
{QString data;bool rt = this->post(url, data, jsonData, timeout);emit finished(data, rt);
}
//!
bool Http::post(QString url, QString& data, QByteArray jsonData, int timeout)
{int repeatSend = 0;//while(!repeatPost(url, data, jsonData, timeout)){++repeatSend;if(++repeatSend >= 3)return false;}return true;
}//
bool Http::repeatPost(QString& url, QString& data, QByteArray& jsonData, int& timeout)
{//QEventLoop loop;//QNetworkRequest request;request.setUrl(QUrl(url));request.setHeader(QNetworkRequest::ContentTypeHeader, "text/xml;charset=UTF-8");//QNetworkAccessManager manager;connect(&manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit);//QTimer timer;timer.setSingleShot(true);connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);//QNetworkReply* pReply = manager.post(request, jsonData);connect(pReply, &QNetworkReply::finished, &loop, &QEventLoop::quit);connect(pReply, SIGNAL(error(QNetworkReply::NetworkError)), &loop, SLOT(quit()));//timer.start((timeout > 0) ? timeout : 2000);loop.exec();//! 超时if(!timer.isActive()){pReply->deleteLater();return false;}//!timer.stop();//QNetworkReply::NetworkError err = pReply->error();if(err != QNetworkReply::NoError){//! 检测状态码int statusCode  = pReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();qDebug()<<"get error, statusCode = "<<statusCode;//! 重定向const QVariant redirectionTarget = pReply->attribute(QNetworkRequest::RedirectionTargetAttribute);if(!redirectionTarget.isNull()){QUrl redirectedUrl = redirectionTarget.toUrl();url = redirectedUrl.toString();}return false;}//!data = QString::fromUtf8(pReply->readAll());pReply->deleteLater();return true;
}

总结

学啥记啥,好记性不如烂笔头!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/199898.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

7-tcp 三次握手和四次挥手、osi七层协议,哪七层,每层有哪些?tcp和udp的区别?udp用在哪里了?

1 tcp 三次握手和四次挥手 2 osi七层协议&#xff0c;哪七层&#xff0c;每层有哪些 3 tcp和udp的区别&#xff1f;udp用在哪里了&#xff1f; 1 tcp 三次握手和四次挥手 # tcp协议---》处于osi7层协议的传输层&#xff0c;可靠连接&#xff0c;使用三次握手&#xff0c;四次挥…

Linux 安装多版本 JDK 详细过程

背景说明 服务器已安装jdk1.8,但随着spring全家桶的升级换代&#xff0c;已不满足使用&#xff0c;先要用高版本jdk&#xff0c;暂时不想卸载旧的版本&#xff0c;故安装两个版本&#xff0c;jdk1.8和jdk17,jdk1.8的已经安装过了&#xff0c;所以此次只安装jdk17,以及配置jdk切…

Android resource/drawable转换成Uri,Kotlin

Android resource/drawable转换成Uri&#xff0c;Kotlin private fun convertResource2Uri(resId: Int): Uri {return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE "://" resources.getResourcePackageName(resId) / resources.getResourceTypeName(resI…

kafka本地安装报错

Error: VM option ‘UseG1GC’ is experimental and must be enabled via -XX:UnlockExperimentalVMOptions. #打开 bin/kafka-run-class.sh KAFKA_JVM_PERFORMANCE_OPTS“-server -XX:UseG1GC -XX:MaxGCPauseMillis20 -XX:InitiatingHeapOccupancyPercent35 -XX:ExplicitGCInv…

〖大前端 - 基础入门三大核心之JS篇㊴〗- DOM节点的关系

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;不渴望力量的哈士奇(哈哥)&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xf…

【广州华锐互动】VR虚拟现实技术助力太空探险:穿越时空,探索宇宙奥秘

随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;技术已经逐渐走进我们的生活。在教育领域&#xff0c;VR技术的应用也日益广泛&#xff0c;为学生提供了更加生动、直观的学习体验。本文将以利用VR开展太空探险学习为主题&#xff0c;探讨如何将这一先进技术…

安装第三方包报错 error: Microsoft Visual C++ 14.0 or greater is required——解决办法

1、问题描述 手动安装第三方软件时&#xff0c;可以使用setup.py&#xff0c;来安装已经下载的第三方包。一般文件下会存在setup&#xff0c;在所要安装库的目录下的cmd执行&#xff1a;python setup.py install报错&#xff1a;error: Microsoft Visual C 14.0 or greater i…

腾讯云COS+picgo+typora 图床搭建与自动上传

1、腾讯云 COS 腾讯云活动 COS新用户专享 COS 操作步骤 1、点击 创建桶&#xff0c;完善信息 点击下一步&#xff0c;剩下的配置可自己配置 2、picgo 官网地址 2.3.1版本下载地址 现在稳定版本是2.3.1 相关连接 腾讯云密钥设置地址picgo官网地址2.3.1版本下载地址

Fourier分析导论——第6章——R^d 上的Fourier变换(E.M. Stein R. Shakarchi)

第6章 上的 Fourier 变换 It occurred to me that in order to improve treatment planning one had to know the distribution of the at- tenuation coefficient of tissues in the body. This in- formation would be useful for diagnostic purposes and would con…

Excel数据可视化—波士顿矩阵图【四象限图】

EXCEL系列文章目录 Excel系列文章是本人亲身经历职场之后萌发的想法&#xff0c;为什么Excel覆盖如此之广&#xff0c;几乎每个公司、学校、家庭都在使用&#xff0c;但是它深藏的宝藏功能却很少被人使用&#xff0c;PQ、BI这些功能同样适用于数据分析&#xff1b;并且在一些需…

Revive开发商加入VR开源标准OpenXR

作为一款能让HTC Vive用户玩到Oculus平台游戏的软件&#xff0c;它的开发商CrossVR今日宣布即将加盟为VR和AR应用程序开源组织&#xff0c;即OpenXR。 由Khronos Group引领的OpenXR旨在创建一个标准化且免版税的应用程序编程接口&#xff08;API&#xff09;&#xff0c;该API…

计算机毕业设计选题推荐-内蒙古旅游微信小程序/安卓APP-项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

代码随想录第六十三天 | 单调栈:寻找 左边 / 右边 距离当前元素最近的 更小 元素的 下标(暴力,双指针,单调栈)(84);代码随想录主要题目结束

1、寻找 左边 / 右边 距离当前元素最近的 更小 元素的 下标 1.1 leetcode 84&#xff1a;柱状图中最大的矩形 第一遍代码思路错了&#xff0c;如&#xff1a;输入[2,1,2]&#xff0c;对于2&#xff0c;因为比栈顶元素1大&#xff0c;然后就会直接得出2&#xff08;1&#xff…

PaaS、 IaaS 和 SaaS 的区别

我感觉我有点捂了 iaas&#xff0c;paas&#xff0c;和saas的区别&#xff0c;以及他们啥意思了 简单说就是&#xff0c;一个公司有很多项目&#xff0c;要管理这些项目&#xff0c;每个项目都有很多组成部分需要管理的地方&#xff0c;例如&#xff0c;存储代码&#xff0c;例…

HTML5学习系列之项目实战1

HTML5学习系列之项目实战1 前言代码记录问题总结 前言 学习记录 代码 <div id"player"><audio id"musicbox"></audio><div id"controls" class"clearfix controls"><div id"play" class"…

uniapp中实现圆形进度条的方式有哪些?

前言 在uniapp开发小程序或者apk时&#xff0c;页面需要用到一个圆形进度条&#xff08;带文字和百分比的&#xff09;&#xff0c;自己也自定义过一个,但是有一点小问题&#xff0c;咱先展示如何引入插件市场的在介绍自定义的&#xff01;一共四种&#xff0c;但是你需要考虑自…

高压放大器使用方法介绍

高压放大器是一种用于放大高压信号的电子设备&#xff0c;常用于科学研究、工业应用和医疗设备等领域。它可以将低电压信号放大到较高的电压水平&#xff0c;以满足特定应用的需求。 使用高压放大器需要注意以下几个方面&#xff1a; 1.了解设备规格&#xff1a;在使用高压放大…

0时区格林威治时间转换手机当地时间-Android

假设传入的是2023-11-01T12:59:10.420987这样的格式 要将格式为2023-11-01T12:59:10.420987的UTC时间字符串转换为Android设备本地时间&#xff0c;您可以使用java.time包中的类&#xff08;在API 26及以上版本中可用&#xff09;。如果您的应用需要支持较低版本的Android&…

【外汇天眼】交易之路:从无知到觉醒,揭秘成功交易员的五个成长阶段

世界顶尖交易员的成功背后隐藏的真正秘诀引人瞩目。许多人梦想着像电影中的主角一样&#xff0c;成为一名成功的金融交易员。尽管开设交易账户相对简单&#xff0c;但要达到稳定盈利的境界确实非常不容易。众所周知&#xff0c;在衍生品市场中&#xff0c;有80%甚至90%以上的交…

网络安全涉及哪些方面?

1.系统安全&#xff1a;运行系统安全即保证信息处理和传输系统的安全。它侧重于保证系统正常运行&#xff0c;避免因为系统的损坏而对系统存储、处理和传输的消息造成破坏和损失&#xff0c;避免由于电磁泄露&#xff0c;产生信息泄露&#xff0c;干扰他人或受他人干扰。 2. 网…