Qt http网络编程

news2024/9/24 19:24:37

学习目标:Qt HTTP网络编程

学习内容

1、Http就是超文本传输协议(Hypertext Transfer Protocol)的缩写,它定义了浏览器和网页服务器之间的通信规范。是一个简单的请求一响应协议,它通常运行在 TCP 之上。

作用:规定 WWW 服务器与浏览器之间信息传递规范,是二者共同遵守的协议。
2.http 工作原理:HTTP 是基于客户/服务器模式,且面向连接的。HTTP 事务处理流程

  1. 客户与服务器建立连接;
  2. 客户向服务器提出请求;
  3. 服务器接受请求,并根据请求返回相应的文件作为应答:
  4. 客户与服务器关闭连接。

Qt 两种方式实现HTTP操作

1. 使用QNetworkAccessManager和QNetworkReply类:

  1. - QNetworkAccessManager是Qt的网络访问管理器,负责发送和接收HTTP/HTTPS请求。
  2. - 通过QNetworkAccessManager::get/post等发起GET/POST等请求,返回QNetworkReply对象。
  3. - 从QNetworkReply中获取响应码、头信息、内容等。实现同步和异步请求。

2. 使用QHttpEngine和QHttpNetworkRequest/Reply类(较低层级):

  1. - QHttpEngine负责管理HTTP连接并处理请求。
  2. - 使用QHttpNetworkRequest构建请求,通过QHttpEngine发送。 
  3. - 解析返回的QHttpNetworkReply获取响应。

一般来说,对于简单的HTTP操作,使用高层的QNetworkAccessManager接口就足够了。它可以方便地处理常见需求。

如果需要更低级的控制,如定制HTTP引擎或请求/响应细节,可以使用QHttpEngine等低层类。

总之,Qt提供了完整的HTTP客户机实现,开发者可以根据实际需求选择更合适的接口进行网络通信操作。这对开发Qt应用提供很好的支持。

总结:

第一种:QNetworkAccessManager 网络连接管理员, 2个行为:get/post 获取或提交请求,返回对象QNetworkReply里面有各种连接信息。

第二种:QHttpEngine 只管理连接请求,不负责发送,

  • 使用QHttpNetworkRequest构建请求,通过QHttpEngine发送。

  • 解析返回的QHttpNetworkReply获取响应。

项目效果和核心代码

http读取器

http服务器

核心代码 

http读取器

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>


#include <QtNetwork> // 提供编程TCP/IP客户端和服务器的类
#include <QUrl> // 提供接口使用URLs


QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();


private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
    QNetworkAccessManager* accesssMgr;
};
#endif // MAINWINDOW_H


#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    accesssMgr =new QNetworkAccessManager(this);

    QObject::connect(accesssMgr,QOverload<QNetworkReply*>::of(&QNetworkAccessManager::finished),this,
                     [this](QNetworkReply* reply){
            QString read=reply->readAll();
            ui->textBrowser->setText(read);
            reply->deleteLater();  //释放
    });

}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_clicked()
{
     ui->label->setText("数据正在下载中,请耐心等待......");
     QString url=ui->textEdit->toPlainText();
     qDebug()<<url;
     accesssMgr->get(QNetworkRequest(QUrl(url)));
}

http服务器

#include "httpserver.h"

HttpServer::HttpServer(QObject *parent) : QObject(parent)
{
    server =new QTcpServer(this);
    //连接回调
    connect(server,&QTcpServer::newConnection,this,&HttpServer::MyselfNewConnectCalllSlot);
    //开始监听
    if(!server->listen(QHostAddress::Any,8088))
    {
        qDebug()<<"\n致命错误:Web服务器没有启动,请重新检查!"<<endl;
    }
    else
    {
        qDebug()<<"\n正常启动:Web服务器端口:8088,等待客户端连接......"<<endl;;
    }
}
void HttpServer::MyselfNewConnectCalllSlot(){
    socket = server->nextPendingConnection();  //获取连接
    while(!(socket->waitForReadyRead(100))); //等待套接字是否有可读数据。 一直阻塞线程等待,直到有可读数据到达套接字,或者超时返回。

    QString webdata;
    webdata.resize(1000);
    webdata=socket->read(1000);

    qDebug()<<"正常运行:从浏览器读取数据信息......"<<webdata;

    //封装http协议
    socket->write("HTTP/1.1 200 OK\r\n");
    socket->write("Content-Type: text/html\r\n");
    socket->write("Connection: close\r\n");
    socket->write("Refresh: 3\r\n\r\n"); // 每秒刷新Web浏览器
    socket->write("<!DOCTYPE>"
                  "<html>"
                  "<header>"
                  "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>"
                  "<title>HttpServer</title>"
                  "</header>"
                  "<body>客户端已经连接HttpSever服务器秒数为:");

    QByteArray byte;
    static qint16 icount=0;
    byte.setNum(icount++);
    socket->write(byte);
    socket->write("</html>");
/*
flush() 不会等待数据真正发送出去,只是把数据从本地缓冲区 flush 到内核缓冲区。
如果输出缓冲区没有数据,flush() 有可能不做任何操作。
调用 flush() 可以确保目前为止写到 socket 的所有数据都发送给对端,而不是 buffered 在本地。
一般在发送完请求或应答后调用,保证数据及时发送出去。
*/
    socket->flush(); //刷新 socket 对象的输出缓冲区。 并发送


    connect(socket, &QTcpSocket::disconnected, socket, &QTcpSocket::deleteLater);
    socket->disconnectFromHost();
}

 

总结

http是基于tcp的应用层协议,所以会使用到tcp的类,协议封装 是固定的。主要成员函数设计

请求:
GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0...
Accept: text/html

响应:
HTTP/1.1 200 OK
Date: Mon, 27 Jan 2020 08:12:31 GMT  
Server: Apache/2.4.1 (Unix)
Last-Modified: Wed, 22 Jul 2020 19:15:56 GMT
ETag: "49092-5b6-52c65aa32f280"
Accept-Ranges: bytes
Content-Length: 438
Connection: close
Content-Type: text/html; charset=UTF-8

<html>
<head>
  <title>Welcome to example.com!</title>
</head>
<body>
  <h1>Hello World!</h1>
  <p>This is the hello world page for an example website.</p> 
</body>
</html>


这个示例演示了一个简单的HTTP请求和响应过程:
客户端发送GET请求获取index.html页面
服务器返回200状态码,表示请求成功
返回各种报头如日期、服务器信息等
返回HTML页面内容作为响应体

 

Qt HTTP编程的主要类是QNetworkAccessManager、QNetworkRequest和QNetworkReply。

QNetworkAccessManager:

  • 管理与网络的连接和请求。发送和接收数据。

  • 提供诸如get()、post()、put()等高级函数发起HTTP请求。

  • Signals: finished(), authenticationRequired()等。

QNetworkRequest:

  • 代表一个HTTP请求。包含URL、 headers等属性。

  • 设置请求方法、内容类型、头信息等。

QNetworkReply:

  • 代表一个HTTP响应。返回状态码和内容。

  • Signals: downloadProgress(), error()等通知处理结果。

  • 功能函数如readAll()读取响应内容。

主要使用步骤:

  1. 创建QNetworkAccessManager对象实例。

  2. 创建QNetworkRequest对象设置URL和属性。

  3. 调用QNetworkAccessManager::get()或post()等函数进行请求。

  4. 监听QNetworkReply的signals获取结果。

  5. 通过QNetworkReply读取内容,或处理错误。

  6. 删除QNetworkReply和请求对象防止内存泄漏。

最后附上源代码链接
对您有帮助的话,帮忙点个star

Qt demo: 学习qt过程 (gitee.com)

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

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

相关文章

【卡尔曼滤波器】DR_CAN 2 学习笔记:_数据融合_协方差矩阵_状态空间方程_观测器问题

【卡尔曼滤波器】2_数学基础_数据融合_协方差矩阵_状态空间方程_观测器问题 非常重要1 数据融合 data fusion 有俩秤,各自有自己的正态分布:俩秤是相互独立的:俩秤都不准,但标准差都符合正态分布 正态分布又叫做高斯分布 向左、向右 都是2, 标准差是2覆盖了68.4 %的可能:…

Oracle RMAN增量备份

1、查询哪部分的增量 sql>set line 500 pages 0 sql>select sequence#,applied,first_change#||,next_change#||,to_char(completion_time,yyyy-mm-dd hh24:MI:SS) from v$archived_log where completion_time>sysdate-1; 2、rman备份(并行保存到指定路径) run{all…

GitLab CI/CD实现项目自动化部署

1 GitLab CI/CD介绍 GitLab CI/CD 是 GitLab 中集成的一套用于软件开发的持续集成&#xff08;Continuous Integration&#xff09;、持续交付&#xff08;Continuous Delivery&#xff09;和持续部署&#xff08;Continuous Deployment&#xff09;工具。这套系统允许开发团队…

org.springframework.boot.autoconfigure.EnableAutoConfiguration=XXXXX的作用是什么?

org.springframework.boot.autoconfigure.EnableAutoConfigurationXXXXXXX 这一配置项在 Spring Boot 项目中的作用如下&#xff1a; 自动配置类的指定&#xff1a; 这一配置将 EnableAutoConfiguration 设置为 cn.geek.javadatamanage.config.DataManageAutoConfiguration&…

react学习——25redux实现求和案例(完整版)

1、目录结构 2、count/index.js import React, {Component} from "react"; //引入store,用于获取数据 import store from ../../redux/store //引入actionCreator 专门创建action对象 import {createDecrementAction,createIncrementAction} from ../../redux/coun…

Linux基础知识(十六)shell脚本编程

一、简介 用户通过shell向计算机发送指令计算机通过shell给用户返回指令的执行结果 1.1 通过shell编程可以达到的效果 提高工作效率可以实现自动化 1.2 需要学习的内容 Linuxshell的语法规范 1.3 编写shell的流程 第一步&#xff1a;用vi/vim创建一个.sh的文件第二步&am…

利用原生JavaScript实现匹配搜索结果的网页内容高亮

昨天在用Anki的时候&#xff0c;复习笔记时想在笔记的解析里快速查找内容&#xff0c;于是探索了一下将匹配的搜索结果高亮。开始想不用第三方库直接实现&#xff0c;结果匹配的文本被HTML标签隔断时不能成功匹配&#xff0c;后来用到了jquery的mark.js库才简单实现。事后我想看…

vue中v-if与v-show的区别

在 Vue.js 中&#xff0c;v-if 和 v-show 都是用来控制元素显示与隐藏的指令&#xff0c;但它们之间有几个关键的区别&#xff1a; 直接上图 一. 条件渲染方式不同 v-if&#xff1a; 真正的条件渲染&#xff1a;v-if 指令会根据表达式的真假来销毁或重新创建 DOM 元素及其…

拟合衰减振动模型,估算阻尼比和阻尼系数

拟合衰减振动模型&#xff0c;估算阻尼比和阻尼系数 flyfish 衰减振动模型 在自由振动系统中&#xff0c;阻尼振动可以用以下公式描述&#xff1a; x ( t ) x 0 e − ζ ω n t cos ⁡ ( ω d t ϕ ) x(t) x_0 e^{-\zeta \omega_n t} \cos(\omega_d t \phi) x(t)x0​e−…

数据结构与算法-动态规划-三角形最小路径和

三角形最小路径和 给定一个三角形 triangle &#xff0c;找出自顶向下的最小路径和。 每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 1 的两个结点。也就是说&#xff0c;如果正位于当前行的下标 i &…

JUC并发编程-05:线程高级部分-源码解读

线程高级部分-源码解读 多线程高并发底层锁机制与优化最佳实践深入JDK源码理解LongAdder的分段CAS优化机制 公平锁和非公平锁原理解析 多线程高并发底层锁机制与优化最佳实践 深入JDK源码理解LongAdder的分段CAS优化机制 多个线程进入&#xff0c;为了防止空转&#xff0c;所…

Android11 窗口动画

窗口进入动画 应用端窗口绘制完成之后&#xff0c;调用finshDraw告知WMS&#xff0c;WMS这边最后就会调用WindowSurfacePlacer的performSurfacePlacement方法&#xff0c;最终调用到 WindowStateAnimator的commitFinishDrawingLocked方法 //frameworks/base/services/core/jav…

基于Transformer的端到端的目标检测 | 读论文

本文正在参加 人工智能创作者扶持计划 提及到计算机视觉的目标检测&#xff0c;我们一般会最先想到卷积神经网络&#xff08;CNN&#xff09;&#xff0c;因为这算是目标检测领域的开山之作了&#xff0c;在很长的一段时间里人们都折服于卷积神经网络在图像处理领域的优势&…

Redis 主从复制,集群与高可用

虽然Redis可以实现单机的数据持久化&#xff0c;但无论是RDB也好或者AOF也好&#xff0c;都解决不了单点宕机问题&#xff0c;即一旦单台 redis服务器本身出现系统故障、硬件故障等问题后&#xff0c;就会直接造成数据的丢失 此外,单机的性能也是有极限的,因此需要使用另外的技…

数字安全护航技术能力全景图 | 亚信安全实力占据75领域

近日&#xff0c;2024全球数字经济大会——数字安全生态建设专题论坛在北京成功举办。会上&#xff0c;中国信息通信研究院&#xff08;简称“中国信通院”&#xff09;正式发布了《数字安全护航技术能力全景图》&#xff0c;亚信安全凭借全面的产品技术能力&#xff0c;成功入…

蓝卓创始人褚健:工业软件是数字化转型的灵魂和核心驱动力

如果把“工业3.0”简单理解为就是“自动化”&#xff0c;“工业4.0”理解为是“智能化”&#xff0c;那么“智能化”的实现一定要有软件。如同今天的移动互联网&#xff0c;是因为有大量的APP&#xff0c;所以让人们进入了智能时代。映射到工业、制造业领域&#xff0c;就是要依…

[GICv3] 4. 中断分发和路由(Distribution and Routing)

&#x1f4a1;介绍如何将中断分发和路由到目标PE&#xff0c;以及中断号的分配。 分发和重分发&#xff08;The disributor an Redistributors&#xff09; 分配器为SPI提供路由配置&#xff0c;并持有所有相关的路由和优先级信息。重新分配器提供PPI和SGI的配置设置。 重新分…

京东速运|通过python查询快递单号API

本次讲解如何使用快递聚合供应商来实现查询京东速运快递物流轨迹&#xff0c;首先&#xff0c;我们需要准备的资源。 平台的密钥key&#xff1a;登录后在个人中心查看 测试接口的链接&#xff1a;在下方文档处查看 其中&#xff0c;KEY为用户后台我的api页面展示的API密钥, 代…

《米小圈漫画历史》:历史启蒙,看漫画书就可以啦!

在当今信息爆炸的时代&#xff0c;如何让孩子在娱乐中学习&#xff0c;一直是许多家长关心的问题。《米小圈漫画历史》系列作为一部集合了趣味性和教育性的漫画书&#xff0c;以其独特的视角和精彩的故事情节&#xff0c;成为了许多家庭历史启蒙的首选。本文将通过探索漫画书的…

MT3046 愤怒的象棚

思路&#xff1a; a[]存愤怒值&#xff1b;b[i]存以i结尾的&#xff0c;窗口里的最大值&#xff1b;c[i]存以i结尾的&#xff0c;窗口里面包含✳的最大值。 &#xff08;✳为新大象的位置&#xff09; 例&#xff1a;1 2 3 4 ✳ 5 6 7 8 9 则ans的计算公式b3b4c4c5c6b7b8b9…