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# 页面依旧回…

在Ubuntu上用sane api实现通用扫描功能

最近由于工作需要&#xff0c;要写一套扫描相关的接口。 在这里记录一下&#xff0c;实现还有有点复杂的。 目录 依赖 主要功能 初始化 获取当前扫描仪列表 打开扫描仪 sane_open 设置扫描选项 sane_control_option 扫描 关闭设备 结束使用 参考资料 依赖 sudo a…

极域电子教室-教师机无法找到学生机

软件环境 极域电子教室2016 V6豪华版 场景还原 因为某软件安装闪退&#xff0c;只能使用自己的电脑进行控制演示&#xff0c;故拔掉原来教室机的网线。 恢复网络后&#xff0c;发现控屏软件无法找到台下的任何学生机。 PS: 拔掉网线前还是可以控制学生机 原因排查 1、网…

操作系统(六)| 文件系统下 文件使用 共享 保护

目录 4 空闲存储空间的管理 4.1 空闲区表 4.2 空闲块链 4.3 位图 5 文件的使用 6 文件共享 6.1 普通的文件共享方法 6.1.1 按路径名访问共享文件 6.1.2 链接法 6.1.3 基本文件目录BFD 6.2 基于I节点的文件共享方法&#xff08;Unix采用&#xff09; 6.2.1 硬链接 6…

transformer学习资料

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

课程32:.Net Core Web API部署IIS

这里写目录标题 🚀前言前言一、服务器环境配置1.1 安装 ASP.NET Core模块/托管捆绑包1.2 检查是否安装成功二、项目发布2.1 选择发布方式2.2 发布配置2.3 发布三、服务器部署3.1 IIS添加网站3.2 数据库链接配置3.3 让IIS支持.NET Web Api3.4 验证四、最后🚀前言 本文是《.…

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…

【周报2023-11-17】

周报2023-11-17 本周的主要工作下周的工作内容 本周的主要工作 本周的主要工作的话主要是小程序页面的搭建 那截止到目前也就是今天为止的话&#xff0c;小程序的主题页面已完成百分之80% 那剩下的话就是一些细节性的问题&#xff1a;例如说首页的三张图片是一个动态轮播动画 …

SpringBoot中文乱码问题解决方案

在Spring Boot中&#xff0c;确实没有像传统Web应用程序中需要使用web.xml配置文件。对于中文乱码问题&#xff0c;你可以采取以下几种方式来解决&#xff1a; 在application.properties文件中添加以下配置&#xff1a; spring.http.encoding.charsetUTF-8 spring.http.encod…

基于轻量级yolov5的瓷砖瑕疵检测系统

该专栏仅支持购买本专栏的同学学习使用,不支持以超级会员、VIP等形式使用,请谅解!【购买专栏后可选择其中一个完整源码项目】 本文是我新开设的专栏《完整源码项目实战》 的第十二篇全源码文章,包含数据集在内的所有资源,可以实现零基础上手入门学习。前面系列文章链接如下…

714. 买卖股票的最佳时机含手续费

给定一个整数数组 prices&#xff0c;其中 prices[i]表示第 i 天的股票价格 &#xff1b;整数 fee 代表了交易股票的手续费用。 你可以无限次地完成交易&#xff0c;但是你每笔交易都需要付手续费。如果你已经购买了一个股票&#xff0c;在卖出它之前你就不能再继续购买股票了…

基于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…

syslog-ng 发送metric 到 Prometheus + Grafana

1: 背景: syslog-ng 作为很多linux 收集日志的重要工具,当然很多splunk 的source 也是用这个收集的,下面就介绍用 Prometheus来收集数据,然后发送到 grafana 来展示,还是很直观的。下面就来详细道来: 2: 安装 syslog-ng node exporter: Prometheus: syslog-ng exporte…

11月20日,每日信息差

今天是2023年11月20日&#xff0c;以下是为您准备的10条信息差 第一、Aboitiz与可口可乐欧洲合作伙伴公司宣布联合收购可口可乐菲律宾公司 第二、微软首席执行官纳德拉&#xff1a;OpenAI创始人Sam Altman和Brockman将加入微软 第三、WeLab于印尼推出旗下第二家数字银行 第…