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.hqwc.cn/news/197803.html

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

相关文章

EasyDSS视频直播点播平台出现断流该如何重连?具体步骤是什么?

视频推拉流EasyDSS视频直播点播平台&#xff0c;集视频直播、点播、转码、管理、录像、检索、时移回看等功能于一体&#xff0c;可提供音视频采集、视频推拉流、播放H.265编码视频、存储、分发等视频能力服务。 近期有用反馈&#xff0c;在EasyDSS平台上所有的直播和码率都是断…

【网络通信】浅析UDP与TCP协议的奥秘

在现代互联网中&#xff0c;UDP&#xff08;用户数据报协议&#xff09;和TCP&#xff08;传输控制协议&#xff09;是两种最常用的传输协议&#xff0c;它们被广泛应用于网络数据传输。尽管这两种协议都可以用来在网络上传输数据&#xff0c;但它们在设计目标、特点和适用场景…

如何写好一篇软文?怎样写软文比较有吸引力?

软文&#xff0c;即柔性广告&#xff0c;是一种通过文字、图片等形式&#xff0c;将广告信息融入到内容中&#xff0c;以达到宣传、推广、营销目的的文章。企业和品牌每天都会在互联网上投放大量软文&#xff0c;软文起到润物细无声的作用&#xff0c;可以在无形中影响用户心智…

C编译环境和预处理(非常详细,建议收藏)

C编译环境和预处理&#xff08;非常详细&#xff0c;建议收藏&#xff09; 一、程序的翻译环境和执行环境二、 详解编译链接2.1 翻译环境2.2 编译本身的几个阶段符号汇总、符号表、合并段表、符号表的合并和重定位分别是什么&#xff1f; 2.2 运行环境 三、预处理详解3.1 预定义…

java基础练习缺少项目?看这篇文章就够了(下)!

公众号&#xff1a;全干开发 。 专注分享简洁但高质量的动图技术文章&#xff01; 回顾 在上节内容中&#xff0c;我们实现了用户开户的功能createAccount public void start(){System.out.println("欢迎您进入到了ATM系统");System.out.println("1、用户登录&…

滚珠螺杆在航天工业领域中的重要性

滚珠螺杆是重要的航天工业配件之一&#xff0c;在航天工业领域中具有非常重要的地位和作用。 首先&#xff0c;滚珠螺杆作为一种高精度、高刚度的传动元件&#xff0c;能够提供准确的传动和定位精度&#xff0c;从而保证航天器的可靠性和性能。航天器在飞行过程中需要精确控制其…

【算法挨揍日记】day21——64. 最小路径和、174. 地下城游戏

64. 最小路径和 64. 最小路径和 题目描述&#xff1a; 给定一个包含非负整数的 m x n 网格 grid &#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 说明&#xff1a;每次只能向下或者向右移动一步。 解题思路&#xff1a; 状态表示&…

[Kettle] 获取系统信息

系统信息是指Kettle系统环境的信息&#xff0c;包括了计算机系统的日期、星期等时间类型信息&#xff0c;计算机名称、IP地址等设备信息&#xff0c;Kettle系统转换过程中的信息等 需求&#xff1a;为方便读取计算机上的本月最后一天的交易数据文件&#xff0c;需要通过获取系…

excel-gen.js 导出excel 功能

目录 概要 整体架构流程 html部分&#xff1a; js部分&#xff1a; json部分&#xff1a; 小结 概要 功能会使用到如下插件&#xff1a; jszip.min.js FileSaver.js jquery.min.js excel-gen.js highcharts.js exporting.js export_data.js 主要是highcharts图表…

移动端获取ua头的值

目录&#xff1a; 1、检测地址2、测试结果 1、检测地址 http://www.ip138.com/useragent/ 2、测试结果 成功的拿到了ua头的值了&#xff0c;亲测可行&#xff01;&#xff01;&#xff01;

三十分钟学会Linux

Linux 一、配置虚拟机 企业级应用&#xff1a;RHEL/CentOS 桌面平台&#xff1a;Ubuntu 开源服务器&#xff1a;CentOS 1.配置网络 路径可以通过TAB键自动补齐 vi /etc/sysconfig/network-scripts/ifcfg-ens332.克隆虚拟机 链接克隆&#xff1a; 当前节点文件夹只存储差…

海外IP代理如何助力跨境电商?

黑五作为下半年年度尤为重要的一个节日&#xff0c;是各大商家的必争之地&#xff0c;那么海外代理是如何帮助跨境商家做好店铺管理和营销呢&#xff1f; 为什么跨境人都关注海外代理&#xff0c;下面我们来进行介绍。 一、什么是海外代理 海外代理就是我们所说的&#xff1a…