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.mzph.cn/news/150311.shtml

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

相关文章

海外代理IP如何找到靠谱的?

现在市面上有很多代理服务商&#xff0c;大家可以根据自己的需求选择一个适合自己业务的的IP代理服务商&#xff0c;现在也有一些免费的&#xff0c;但如果力求稳定安全&#xff0c;还是选择付费的。 这里提醒一句&#xff0c;在买代理IP时最好找这种可以免费试用的&#xff0…

虾皮台湾站点如何选品

在互联网时代&#xff0c;电商平台成为了越来越多人购物的首选。虾皮作为台湾地区最大的电商平台之一&#xff0c;为商家提供了良好的销售渠道。然而&#xff0c;在虾皮上选择适合的商品对于商家来说并不容易。本文将介绍如何通过虾皮选品工具-知虾来查看台湾地区各大类目的热销…

⑩⑤【DB】详解MySQL存储过程:变量、游标、存储函数、循环,判断语句、参数传递..

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ MySQL存储过程 1. 介绍2. 使用3. 变量①系统变…

Polygon zkEVM协议治理、升级及其流程

1. 引言 随着Polygon社区开发者和内部团队的测试深入&#xff0c;当前版本的Polygon zkEVM不可避免地需更新和某些升级。 为激励开发者对Polygon zkEVM做battle-test&#xff0c;已启动了bug-bounty&#xff1a; Rewards by Threat Level 由于zk-Rollup生态系统还处于萌芽阶…

【libGDX】ApplicationAdapter生命周期

1 前言 libGDX 中&#xff0c;用户自定义的渲染窗口需要继承 ApplicationAdapter 类&#xff0c;ApplicationAdapter 实现了 ApplicationListener 接口&#xff0c;但实现的方法都是空方法&#xff0c;方法释义如下。 public interface ApplicationListener {// 应用首次创建时…

sql注入 [极客大挑战 2019]HardSQL1

打开题目 输入1或者1"&#xff0c;页面均回显NO,Wrong username password&#xff01;&#xff01;&#xff01; 那我们输入1 试试万能密码 1 or 11 # 输入1 and 12 # 输入1 union select 1,2,3 # 输入1 ununionion seselectlect 1,2,3 # 输入1 # 输入1# 页面依旧回…

transformer学习资料

一、NLP 自然语言处理 NLP 是机器学习在语言学领域的研究&#xff0c;专注于理解与人类语言相关的一切。NLP 的目标不仅是要理解每个单独的单词含义&#xff0c;而且也要理解这些单词与之相关联的上下文之间的意思。 常见的NLP 任务列表&#xff1a; 对整句的分类&#xff1…

Vue.js2+Cesium1.103.0 十四、绘制视锥,并可实时调整视锥姿态

Vue.js2Cesium1.103.0 十四、绘制视锥&#xff0c;并可实时调整视锥姿态 Demo <template><divid"cesium-container"style"width: 100%; height: 100%;"><divclass"control"style"position: absolute;right: 50px;top: 50px…

基于51单片机水位监测控制报警仿真设计( proteus仿真+程序+设计报告+讲解视频)

这里写目录标题 &#x1f4a5;1. 主要功能&#xff1a;&#x1f4a5;2. 讲解视频&#xff1a;&#x1f4a5;3. 仿真&#x1f4a5;4. 程序代码&#x1f4a5;5. 设计报告&#x1f4a5;6. 设计资料内容清单&&下载链接&#x1f4a5;[资料下载链接&#xff1a;](https://doc…

NX二次开发UF_CAM_ask_f_s_db_object 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;里海NX二次开发3000例专栏 UF_CAM_ask_f_s_db_object Defined in: uf_cam.h int UF_CAM_ask_f_s_db_object(UF_CAM_db_object_t * db_obj ) overview 概述 This function provides the database object which is currently u…

yum仓库

目录 什么是yum仓库 概念 yum的实现过程 Yum的实现过程如下&#xff1a; yum的配置文件 仓库设置文件 日志文件 yum命令 yum list 显示所有可用的包&#xff0c;包名&#xff0c;支持通配符 yum list*Kernel yum info 显示包的信息 yum search ftp 查…

【Feign】 基于 Feign 远程调用、 自定义配置、性能优化、实现 Feign 最佳实践

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; SpringCloud MybatisPlus JVM 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 Feign 一、 基于 Feign 远程调用1.1 RestTemplate方式…

笔记53:torch.nn.rnn() 函数详解

参数解释&#xff1a; &#xff08;1&#xff09;input_size()&#xff1a;即输入信息 Xt 的每个序列的独热编码向量的长度&#xff0c;即 len(vocab) &#xff08;2&#xff09;hidden_size()&#xff1a;即隐变量 h 的维度&#xff08;维度是多少&#xff0c;就代表用几个数…

Keras训练一个基本体系化的分类模型流程案例

Keras训练一个基本体系化的分类模型流程案例 import numpy as np from keras.datasets import mnist from keras.utils import np_utils # 导入keras提供的numpy工具包 from keras.models import Sequential from keras.layers import Dense from keras.optimizers impo…

unity 打包exe设置分辨率

unity在2019以上版本不支持在打开的时候弹出分辨率设置的窗口&#xff0c;但是因为有些需求需要可以设置分辨率进行操作&#xff0c;我在查了好多办法后找到了解决方案&#xff0c;废话不多说开始干货。 1.先去百度云上下载这个文件 链接&#xff1a;https://pan.baidu.com/s/1…

LeetCode Hot100之十:239.滑动窗口最大值

题目 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 提示&#xff1a; 1 < nums.length < 10^5 -10^4 < nums[i…

BUG 随想录 - Java: 程序包 com.example.xxx 不存在

目录 一、BUG 复现 二、解决问题 一、BUG 复现 背景&#xff1a;通过 feign 的最佳实践&#xff0c;将 feign 单独提取成一个微服务&#xff0c;接着在需要远程调用的微服务中引入 feign 模块&#xff0c;并在启动类通过 EnableFeignClients 声明指定的 Feign 客户端. 出现问题…

LENOVO联想ThinkBook 16p G2 ACH(20YM)2022款锐龙版原厂Win11预装系统镜像

链接&#xff1a;https://pan.baidu.com/s/14AATH2NYsLwK9jMpej2BNw?pwd53sy 提取码&#xff1a;53sy 原装出厂W11系统自带网卡、显卡、声卡、蓝牙等所有驱动、出厂时状态主题壁纸、Office办公软件、联想电脑管家等预装程序 所需要工具&#xff1a;16G或以上的U盘 文件格…

面试官:你能说说常见的前端加密方法吗?

给大家推荐一个实用面试题库 1、前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;web前端面试题库 前言 本篇文章略微介绍一下前端中常见的加密算法。前端中常见的加密算法主要形式包括——哈希函数&#xff0c;对称…

十八数藏的文化新生:数字创新的非遗保护之光

在数字时代的大舞台上&#xff0c;十八数藏如一颗璀璨的文化新星&#xff0c;以数字创新的光芒点亮着非遗保护的未来。这不仅仅是一次文化的复兴&#xff0c;更是对传统之美的数字赋能&#xff0c;让非遗在新的时代焕发出勃勃生机。 十八数藏通过数字化手段&#xff0c;使得传统…