QT5实现https的post请求(QNetworkAccessManager、QNetworkRequest和QNetworkReply)
QT5实现https的post请求
- 前言
- 一、一定要有sslErrors处理
- 1、问题经过
- 2、代码示例
- 二、要利用抓包工具
- 1、问题经过
- 2、wireshark的使用
- 3、利用wireshark查看服务器地址
- 4、利用wireshark查看自己构建的请求报文
- 三、返回数据只能读一次
- 1、问题描述
- 2、部分代码
- 总结
前言
- QNetworkAccessManager、QNetworkRequest和QNetworkReply是QT5网络编程的API,三者共同完成HTTP或者HTTPS协议的通信。
- 初学者往往会程序编译没有问题,但是运行代码没有任何结果,于是不知道问题出在哪里。此时,要借助
postman、wireshark等工具的帮助。
本文按照问题出现的顺序总结QT5的网络编程方法。
一、一定要有sslErrors处理
1、问题经过
我们知道,客户端发送HTTPS的post请求,需要手动构建请求报文的请求行、请求头部和请求体。一开始的时候,着急利用QNetworkRequest来实现构建请求报文(request),但是程序运行始终没有输出数据,以为是构建报文的格式不正确。于是简化,构建get报文,程序运行依然没有输出数据。后来,参考官网Example、Gitee、CSDN的代码,加入了sslErrors槽函数,程序终于有了反应。在利用QNetworkAccessManager::connectToHostEncrypted时提示错误:qt.network.ssl: QSslSocket: cannot resolve EVP_PKEY_base_id。
这是HTTPS请求错误,原因在于本地OpenSSL版本与Qt支持的不匹配。通过检查、下载、编译和配置OpenSSL源代码,解决了这个问题。具体方法可以参考博文: 《(Linux)解决运行Qt程序时报错》,亲测有效。
如果不加sslErrors槽函数,那永远不知道是OpenSSL的问题,还傻傻地以为是报文格式、post方法不对。
参考资料:QNetworkReply Class | Qt Network 5.15.17
2、代码示例
httpspost.h部分代码如下
class HttpsPost : public QObject
{Q_OBJECTQNetworkAccessManager m_networkAccessManager;public:HttpsPost();void doPost();~HttpsPost();private://发送data数据QByteArray m_sendJsonData;QVariant data;public slots:void sslErrors(const QList<QSslError> &errors);void postReadyRead(QNetworkReply *reply);
}
httpspost.cpp部分代码如下:
#include <QtCore>
#include <QtNetwork>
#include <QSslConfiguration>
#include <QNetworkReply>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonArray>
#include <QDebug>
#include <QVector>#include "httpspost.h"HttpsPost::HttpsPost()
{connect(&m_networkAccessManager, &QNetworkAccessManager::finished, this, &HttpsPost::postReadyRead);#if QT_CONFIG(ssl)connect(reply, &QNetworkReply::sslErrors,this, &HttpsPost::sslErrors);
#endif
}void HttpsPost::sslErrors(const QList<QSslError> &sslErrors)
{
#ifndef QT_NO_SSLforeach(const QSslError &error, sslErrors)qDebug() << "SSL error: " << error.errorString();#elseQ_UNUSED(sslErrors);
#endif
}
QNetworkReply类有信号对象(signals)sslErrors。这个信号可以用来发射、显示错误消息。从而利用自己编写的槽函数HttpsPost::sslErrors来显示、错误处理。
二、要利用抓包工具
1、问题经过
编译、安装了OpenSSL之后,程序运行仍然没有数据输出。此时,考虑到底有没有连接Web服务器,是否发送了post请求,所以想到利用网络抓包工具。我用的是wireshark抓包工具,很好用,360软件管家就有,安全有保障。
2、wireshark的使用
安装好wireshark工具之后,首先用postman发送get、post请求,看看正确的通信过程是怎样的。
①处:添加过滤器,只看本机和Web服务器IP地址的包。
②处:可以看到发送了post请求,点击可以查看请求报文内容。
③处:查看请求报文的格式和内容。根据这个可以比对自己构建的请求报文是否正确。
④处:可以看到协议版本是TLSV1.2。

3、利用wireshark查看服务器地址
服务器的地址可以通过QNetworkRequest类的构造函数来设置。例如:
QNetworkRequest m_httpRequest(QUrl("http://www.wangsansan.com/test/HttpsPostTest.php"));
有2个问题需要注意:
- QUrl地址中,http与https的连接过程、传输协议、端口都是不一样的。
- https服务器地址不能用IP地址(QUrl(“
https://115.28.242.169/test/HttpsPostTest.php”)),否则会报错:
SSL error: "The host name did not match any of the valid hosts for this certificate"。
http服务器则可以用计算机名,也可以用IP地址。
参考资料:QNetworkRequest Class | Qt Network 5.15.17
4、利用wireshark查看自己构建的请求报文
构建请求报文要用到QNetworkRequest类。刚开始的时候,不知道使用setHeader和setRawHeader的效果。利用wireshark就可以查看了。例如,QNetworkRequest::m_httpRequest.setHeader(QNetworkRequest::LocationHeader, QByteArray("/test/HttpsPostTest.php"));的结果如下图所示:

部分代码如下:
void HttpsPost::doPost()
{QJsonDocument doc;QJsonObject jsonObjData;jsonObjData.insert("A", "111"); // 设置内容字段jsonObjData.insert("B", "222"); doc.setObject(jsonObjData);QString str = QString(doc.toJson());QByteArray content = str.toUtf8();int contentLength = content.length();//QSslConfiguration是QNetworkRequest的访问设置类,用于设置协议类型支持httpsQSslConfiguration config;config.setPeerVerifyMode(QSslSocket::VerifyNone);config.setProtocol(QSsl::TlsV1_2); //构建QNetworkRequest对象,设置urlQNetworkRequest m_httpRequest(QUrl("http://www.wangsansan.com/test/HttpsPostTest.php"));//构建post请求报文// m_httpRequest.setHeader(QNetworkRequest::LocationHeader, QByteArray("/test/HttpsPostTest.php"));m_httpRequest.setHeader(QNetworkRequest::ContentTypeHeader, QByteArray("application/json; charset=utf-8"));m_httpRequest.setRawHeader("Connection", QByteArray("keep-alive"));m_httpRequest.setHeader(QNetworkRequest::ContentLengthHeader, doc.toJson().size());//m_sendJsonData.length()reply = m_networkAccessManager.post(m_httpRequest, doc.toJson());//返回数据QNetworkReply *reply = m_networkAccessManager.get(m_httpRequest);
三、返回数据只能读一次
1、问题描述
到这里,向服务器发送post请求已经没有问题了。但是,运行程序仍然无法获取数据。问题应该出在获取返回数据上。刚开始时,复制了官网上的代码,问题依然存在。Gitee、CSDN上的代码,写法也各不相同。后来,看了官网的参考文档才知道,返回数据只能在返回数据结束之后,读一次。
1.The QNetworkReply class contains the data and meta data related to a request posted with QNetworkAccessManager.
2.QNetworkReply is a sequential-access QIODevice, which means that once data is read from the object, it is no longer kept by the device.
QNetworkAccessManager::finished()和QNetworkReply::finished(),都可以发送返回数据结束的信号(signal)。然后用槽函数来获取数据。您还可以使用QNetworkReply::isFinished()来检查QNetworkReply是否已完成。
参考文档:
QNetworkAccessManager Class | Qt Network 5.15.17
QNetworkReply Class | Qt Network 5.15.17
2、部分代码
httpspost.h如上文,httpspost.cpp部分代码如下:
HttpsPost::HttpsPost()
{connect(&m_networkAccessManager, &QNetworkAccessManager::finished, this, &HttpsPost::postReadyRead);#if QT_CONFIG(ssl)connect(reply, &QNetworkReply::sslErrors,this, &HttpsPost::sslErrors);
#endif
}void HttpsPost::postReadyRead(QNetworkReply *reply)
{qDebug() <<"reply data:"<< QString::fromUtf8(reply->readAll());
}
运行结果举例:
reply data: "{\"error_code\":111,\"error_msg\":\"Access token expired\"}"
总结
至此,QT5利用QNetworkAccessManager、QNetworkRequest和QNetworkReply三个类可以实现https的post请求。但是,还有问题需要改进:
- 返回数据的处理
- post请求报文中的正文部分,其格式、内容、字节长度等还需要验证。Jason数据的嵌套还需要实现。
相关文章:
QT5实现https的post请求(QNetworkAccessManager、QNetworkRequest和QNetworkReply)
QT5实现https的post请求 前言一、一定要有sslErrors处理1、问题经过2、代码示例 二、要利用抓包工具1、问题经过2、wireshark的使用3、利用wireshark查看服务器地址4、利用wireshark查看自己构建的请求报文 三、返回数据只能读一次1、问题描述2、部分代码 总结 前言 QNetworkA…...
vscode 使用git bash,路径分隔符缺少问题
window使用bash --login -i 使用bash时候,在系统自带的terminal里面进入,测试conda可以正常输出,但是在vscode里面输入conda发现有问题 bash: C:\Users\marswennaconda3\Scripts: No such file or directory实际路径应该要为 C:\Users\mars…...
F12抓包10:UI自动化 - Elements(元素)定位页面元素
课程大纲 1、前端基础 1.1 元素 元素是构成HTML文档的基本组成部分之一,定义了文档的结构和内容,比如段落、标题、链接等。 元素大致分为3种:基本结构、自闭合元素(self-closing element)、嵌套元素。 1、基本结构&…...
android 删除系统原有的debug.keystore,系统运行的时候,重新生成新的debug.keystore,来完成App的运行。
1、先上一个图:这个是keystore无效的原因 之前在安装这个旧版本android studio的时候呢,安装过一版最新的android studio,然后通过模拟器跑过测试的demo。 2、运行旧的项目到模拟器的时候,就报错了: Execution failed…...
SQL入门题
作者SQL入门小白,此栏仅是记录一些解题过程 1、题目 用户访问表users,记录了用户id(usr_id)和访问日期(log_date),求出连续3天以上访问的用户id。 2、解答过程 2.1数据准备 通过navicat创建数据…...
Python实战:实战练习案例汇总
Python实战:实战练习案例汇总 **Python世界系列****Python实践系列****Python语音处理系列** 本文逆序更新,汇总实践练习案例。 Python世界系列 Python世界:力扣题43大数相乘算法实践Python世界:求解满足某完全平方关系的整数实…...
zabbix之钉钉告警
钉钉告警设置 我们可以将同一个运維组的人员加入到同一个钉钉工作群中,当有异常出现后,Zabbix 将告警信息发送到钉钉的群里面,此时,群内所有的运维人员都能在第一时间看到这则告警详细。 Zabbix 监控系统默认没有开箱即用…...
《OpenCV计算机视觉》—— 对图片进行旋转的两种方法
文章目录 一、用numpy库中的方法对图片进行旋转二、用OpenCV库中的方法对图片进行旋转 一、用numpy库中的方法对图片进行旋转 numpy库中的 np.rot90 函数方法可以对图片进行旋转 代码实现如下: import cv2 import numpy as np# 读取图片 img cv2.imread(wechat.jp…...
Python 错误 ValueError 解析,实际错误实例详解 (一)
文章目录 前言Python 中错误 ValueError: No JSON object Could Be Decoded在 Python 中解码 JSON 对象将 JSON 字符串解码为 Python 对象将 Python 对象编码为 JSON 字符串Python 中错误 ValueError: Unsupported Pickle Protocol: 3Python 中的 Pickling 和 UnpicklingPython…...
[java][git]上传本地代码及更新代码到GitHub教程
上传本地代码及更新代码到GitHub教程 上传本地代码 第一步:去github上创建自己的Repository,创建页面如下图所示: 红框为新建的仓库的https地址 第二步: echo "# Test" >> README.md 第三步:建立g…...
react antd table expandable defaultExpandAllRows 不生效问题
原因:defaultExpandAllRows只会在第一次渲染时触发 解决方案:渲染前判断table 的datasource 数据是否已准备好 {pageList.length > 0 ? (<TablerowSelection{rowSelection}columns{columns}dataSource{pageList}style{{ marginTop: 24 }}pagina…...
什么是领域驱动设计?
什么是领域驱动设计? 领域驱动设计(Domain-Driven Design,简称DDD)是一种面向对象的软件开发方法,它强调将软件系统的设计和实现过程与业务领域紧密结合,通过深入理解和建模业务领域,从而实现高…...
信息安全工程师(1)计算机网络分类
一、按分布范围分类 广域网(WAN): 定义:广域网的任务是提供长距离通信,运送主机所发送的数据。其覆盖范围通常是直径为几十千米到几千千米的区域,因此也被称为远程网。特点:连接广域网的各个结点…...
利士策分享,探索无界:心灵之旅,发现未知精彩
利士策分享,探索无界:心灵之旅,发现未知精彩 梦想的种子,在心田生根发芽 正如每一颗种子都蕴含着生命的奥秘,每个人心中那颗探索的种子,也藏着对未知世界的渴望与追求。它告诉我们,成长不仅仅…...
Jetson 部署 Faster Whisper
文章目录 WhisperFaster Whisper安装使用尝试WSL部署尝试 Jetson 部署时间戳 实时转录 Whisper Whisper 是一种通用语音识别模型。它是在大量不同音频数据集上进行训练的,也是一个多任务模型,可以执行多语言语音识别、语音翻译和语言识别。 测试&#x…...
测试开发基础——测试分类
四、测试分类 1. 按照测试目标分类 1.1. 界面测试 肉眼看到的任何元素都需要进行测试 界面测试(简称U测试),指按照界面的需求(一般是U设计稿)和界面的设计规则,对我们软件界面所展示的全部内容进行测试…...
【计网】数据链路层:概述之位置|地位|链路|数据链路|帧
✨ Blog’s 主页: 白乐天_ξ( ✿>◡❛) 🌈 个人Motto:他强任他强,清风拂山岗! 💫 欢迎来到我的学习笔记! ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ 1. 在OSI体系结构中的位置 1. 位置:数…...
【Android】NestedScrollView的简单用法与滚动冲突、滑动冲突
一、NestedScrollView 1. 什么是 NestedScrollView NestedScrollView 是 Android 中一个用于处理垂直方向滚动的布局组件,它继承自 FrameLayout,同时支持嵌套滑动(Nested Scrolling)机制。相比于传统的 ScrollView,N…...
【LeetCode】每日一题 2024_9_13 预算内的最多机器人数目(滑动窗口、单调队列)
LeetCode 启动! 每日一题的题解重新开始连载! 题目:预算内的最多机器人数目 题目链接:2398. 预算内的最多机器人数目 题目描述 代码与解题思路 func maximumRobots(chargeTimes []int, runningCosts []int, budget int64) (an…...
TypeScript中 any和unknown 的区别
1、给其他变量赋值 any可以给其他类型的变量重新赋值; 但unknown是不行的,unknown 可以保持类型安全,从而减少潜在的错误; 2、使用类型上的方法 any可以用类型上的方法,unknown是不可以的...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决
问题: pgsql数据库通过备份数据库文件进行还原时,如果表中有自增序列,还原后可能会出现重复的序列,此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”,…...
【题解-洛谷】P10480 可达性统计
题目:P10480 可达性统计 题目描述 给定一张 N N N 个点 M M M 条边的有向无环图,分别统计从每个点出发能够到达的点的数量。 输入格式 第一行两个整数 N , M N,M N,M,接下来 M M M 行每行两个整数 x , y x,y x,y,表示从 …...
中科院1区顶刊|IF14+:多组学MR联合单细胞时空分析,锁定心血管代谢疾病的免疫治疗新靶点
中科院1区顶刊|IF14:多组学MR联合单细胞时空分析,锁定心血管代谢疾病的免疫治疗新靶点 当下,免疫与代谢性疾病的关联研究已成为生命科学领域的前沿热点。随着研究的深入,我们愈发清晰地认识到免疫系统与代谢系统之间存在着极为复…...
