QT网络编程

news2024/11/20 15:34:44

Qt 给用户提供了网络编程的接口,包括TCP、UDP、HTTP三种协议的API以及各种类,可以了解一下。

而在 QT 中想要使用网络编程,必须在pro文件中添加 network 模块,否则无法包含网络编程所需的头文件。

UDP

UDP是传输层的协议,该协议是无输出,不可靠,面向数据包,全双工的通信协议。

QT为 UDP 协议专门设置了两个类:QUdpSocket 以及 QNetworkDatagram 。

QUdpSocket类

该类是专门用于 Udp 的类,包含 Udp 协议所需的绑定、接收数据包、发送数据包等API。

bind(const QHostAddress&,quint16)函数绑定端口号类似linux中的bind
receiveDatagram()函数返回一个 QNetworkDatagram类型的数据包类似linux中的recvfrom
writeDatagram()函数发送一个QNetworkDatagram类型的数据包类型linux中的sendto
readyRead信号当一个端口号可以读取时即可触发该信号类似linux中的多路转接:select、poll和epoll等

QNetworkDatagram

该类表明一个数据包,可以从该类所实例化的对象中读取所需的数据、发送端的端口号和 ip 地址

QNetworkDatagram(const QByteArray&,const QHostAddress&,quint16)方法QNetworkDatagram的构造函数,用于创建一个对象
data()方法获取数据包中的数据,返回一个 QByteArray 对象
sederAddress()方法获取数据包发送者的 IP 地址
sederPort()方法获取数据包发送者的 端口号

和Linux不同的是,linux的接收和发送函数:recvfrom 和 sendto ,它们都需要一个  sockaddr 的结构体对象来获取发送端的 IP 地址和端口号,而QT则是将其拆开,数据包中直接包含对端的IP地址和端口号

UDP回显服务器

首先写服务器的代码,在 pro 文件添加 network 模块后,即可使用上述API。

在服务器一侧我们使用 listWidget 控件,用来显示所有接收的数据。 

然后在头文件中添加 QUdpSocket 对象,用来后续接收客户端的消息。 

 

然后在构造函数中我们初始化 socket 后,需要先进行信号槽绑定然后再进行端口号绑定。

 必须先进行信号槽绑定再进行端口号绑定,这是为了防止如果有客户端发起请求了,但是信号槽函数未绑定,导致该请求丢失的情况。

 然后再写好槽函数,写好接收和显示逻辑。

 

UDP回显客户端

同样的,在pro文件中添加network模块后即可使用UDP的API。

客户端需要发送数据和接收数据,因此除了 listWidget 来显示数据之外,还需要 lineEidt 和 pushbutton 两个控件,分别用来输入数据和发送数据。

 

 在头文件中添加控件的槽函数,其他和Server一样。

而在构造函数中,除了初始化 socket 之外,还需要绑定 readyRead 信号和process槽函数,因为客户端也需要接收服务器发送的数据。 

而pushButton 的槽函数就需要先从 lineEdit 中读取文件,然后再创建一个 QNetworkDatagram 对象,用来发送数据,该数据包必须包含服务器的 IP 地址和 端口号。

而接收服务器发送的数据就直接显示在 listWidget 上。 

 

可以看到成功的发送和接收到数据了。

 

TCP

TCP是一个可靠、面向连接、面向字节流、全双工的传输层协议,它的API稍微比UDP复杂,但是也很简单。

其核心类有两个:QTcpServer 和 QTcpSocket。

QTcpServer

该类专门用于监听端口,和获取客户端连接。

listen(const QHostAddress&,quint16)方法绑定指定的端口号和IP地址,并且启动监听类似linx中的bind和listen的结合体
nextPendingConnection()方法

从系统中获取一个已经建立好的tcp连接,返回一个 QTcpSocket 对象。

通过该对象可以进行通信

类似linux 中的 accept
newConnection信号有新的客户端建立好连接后即触发在linux中类似多路转接的通知机制

QTcpSocket

 和 QUdpSocket 类似,该类用于进程间通信。

readAll()方法

读取接收缓冲区的所有数据

返回一个 QByteArray 对象

类似linux中的read
write(const QByteArray & )方法把数据写入 socket 对象中类似linux的write
deleteLater方法将该 socket 对象设为无效,在下一次事件循环中析构该对象类似 java 中的自动回收机制,不过我们这里是半自动的
connectToHost(const QHostAddress&,quint16)方法向服务器发送连接请求,进行三次握手操作类似 linux 中的 connect 函数
readyRead信号有数据到达并准备时触发类似多路复用
disconnected信号当断开连接时触发类似多路复用

通过上面两个类可以实现 TCP 的回显服务器。

TCP回显服务器

和 UDP 的服务器一样,直接用一个 listWidget 用来显示所有数据。 

在头文件上设置好 QTcpServer 对象和槽函数。 

将 QTcpServer 的 newConnection 信号和对应的槽函数绑定,然后启动监听。

当一个客户端发起链接时,分未三个部分。

  • 获取客户端的连接,并显示有客户端上线
  • 绑定 readyRead 和 对应的槽函数(此处用的 lambda 表达式)
  • 绑定 disconnected 和 对应的槽函数 

无论是客户端上线、还是接收到数据、又或者是断开连接,都会在 listWidget 上显示出来。

而 process 函数则是单纯的返回一个相同的QString罢了。 

 

TCP回显客户端 

和 UDP 回显客户端一样,采用 listWidget、lineEdit、pushButton 三个控件。 

头文件中添加 QTcpSocket 类和 pushButton 对应的槽函数。 

而在构造函数中,除了初始化 socket 之外,还需要将 socket 的 readyRead 信号和槽函数绑定在一起,用来显示在 listWidget 中。此外还需要通过 connectToHost 来和服务器建立连接 。

此外由于客户端还需要接收服务器发送的数据,因此也需要绑定函数。

而pushButton的槽函数则直接读取 lineEdit 上的文本,并且发送和服务器。 

 能够发现确实进行了互相通信。

不过让我们回忆下 linux 中我们是如何使用 TCP 进行通信的?

当一个客户端进行请求时,就为该客户端创建一个线程,在线程中进行管理,但是我们这里的QT明显不是这样的,这是为什么呢?实际上那是因为 代码缺陷 linux中采用的是双层循环方式,当一个客户端建立连接,那么直到客户端断开连接之前,服务器一直都会在内层循环中阻塞,无法到达 accept 中去,只能通过多线程的方式进行。 

而 QT 自带信号槽机制就很好的解决了这个问题,当有信号发生时才去处理,而 linux 除非采用 epoll 来将处理之外,基本只能通过多线程解决。

HTTP Client

实际上一个服务器不太可能采用图形化界面的,因此实际上 TCP 和 UDP 都使用的很少。

QT 中使用最多的是 HTTP。

QT 提供三个类用于和 HTTP 进行请求和获取操作。

  • QNetworkAccessManager
  • QNetworkRequest
  • QNetworkReply 

QNetworkAccessManager

该类提供 HTTP 的核心操作。

方法说明
get(const QNetworkRequest&)以get 的方式发送一个请求
post(const QNetworkRequest&,const QByteArray&)以 post 的方式发送一个请求

 当然,HTTP 有很多操作,比如delete、head之类的,不过这里就不一一赘述了。

QNetworkRequest

该类表示一个 Http 请求,不包含body

如果使用 post 发送一个带有 body 的请求,则需要另外单独的参数来传入 body。

方法说明
QNetworkRequest(const QUrl&)通过 URL 构造一个 HTTP 请求
setHeader(QNetworkRequest::KnownHeaders header, const QVariant& value)      设置请求头

其中,这个 setHeader 的 KnownHeader 是一个枚举类型,包括以下类型。

说明
ContentTypeHeader描述body 类型
ContentLengthHeader描述 body 长度
LocationHeader用于重定向报文中指定重定向地址(响应才会用到)
CookieHeader设置 cookie
UserAgentHeader设置 User-Agent

选择了某一个枚举类型后, value 就必须是枚举类型对应的说明,比如如果选择的ContentTypeHeader,那么 value 就需要在 http Body 的四种格式:form-datax-www-from-urlencodedrawbinary 中选一个了。

QNetworkReply

这是 Http 的响应,它是 QIODevice 的子类

名称类型说明
error()方法获取出错状态
errorString()方法获取出错原因的文本
readAll()方法读取响应文本
header(QNetworkRequest::KnownHeaders header)方法读取响应指定header 的值
finished信号客户端收到完整的响应数据后触发

接着我们来试着使用这些API 来获取一个响应。

首先采用 plainTextEdit、lineEdit、pushButton 三个控件。

头文件中新增 QNetworkAccessManager 对象。 

然后在构造函数中初始化 manager。 

而pushButton的槽函数中,我们需要按顺序来发送请求。

首先是通过获取在 lineEdit 中的 文本,并且构建一个 url。

然后通过 url 来创建一个请求,最后通过 get 方法来发送请求,并且获取一个响应。

如果该响应已经接收完所有数据后,就进入响应绑定的槽函数中,将响应显示在 plainTextEdit 上 

 

可以看到确实是获取到了响应。 

 

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

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

相关文章

Animate软件基础:在时间轴中标识动画

FlashASer:AdobeAnimate2021软件零基础入门教程https://zhuanlan.zhihu.com/p/633230084 FlashASer:实用的各种Adobe Animate软件教程https://zhuanlan.zhihu.com/p/675680471 FlashASer:Animate教程及作品源文件https://zhuanlan.zhihu.co…

实战项目导航

目录 1.AI毕设生成器(完善中)2.计算机设计大赛案例3.c迷宫游戏4.python学生管理系统教学关注持续更新哦 1.AI毕设生成器(完善中) 文章链接 🚀 一键启航,编码从未如此简单! 探索Python毕业设计生…

vulnhub之serial

这次我们来做这个靶场 项目地址https://download.vulnhub.com/serial/serial.zip 使用vm新建虚拟机 以下为注意事项 第一步,收集资产 扫描靶场ip netdiscover -i eth0 -r 192.168.177.0/24 抓个包 扫描目录 看到了cookie中有一个user Tzo0OiJVc2VyIjoyOntzOj…

【Golang 面试 - 进阶题】每日 3 题(十八)

✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/UWz06 📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏…

算法:BFS 解决拓扑排序

目录 拓扑排序 题目一:课程表 题目二:课程表II 题目三:火星词典 拓扑排序 有向无环图(DAG图) 有向无环图也就是有几个点,每个点之间的线段都是有向的,且任意拿出来几个点,都是无环的,这里…

Adaboost集成学习 | Matlab实现基于ELM-Adaboost极限学习机结合Adaboost集成学习故障诊断

目录 效果一览基本介绍程序设计参考资料效果一览 基本介绍 Adaboost集成学习 | Matlab实现基于ELM-Adaboost极限学习机结合Adaboost集成学习故障诊断 ELM(Extreme Learning Machine)和 Adaboost 都是机器学习领域中常见的算法。ELM 是一种单隐层前馈神经网络,具有快速训练、…

使用 1panel面板 部署 springboot 和 vue

代码仓库:还没弄 目录 网站介绍安装步骤1. 准备云服务器2. 准备域名(可跳过)3. 安装1panel面板4. 服务器开放端口5. 进入1panel面板6. 安装并启动软件(服务器和面板开放端口)7. 打包并上传项目7.1 打包 Java项目&#…

算力共享中神经网络切片和算力分配策略

目录 神经网络切片 按照算力的分布进行网络层数切片;就是算力越强,运算神经网络层数越多 神经网络切片和算力占比进行映射 算力分配策略 get_current_shard 神经网络切片 按照算力的分布进行网络层数切片;就是算力越强,运算神经网络层数越多 神经网络切片和算力占比进…

基于RK3588+AI支持能源在线监测系统应用的AIOT产品方案

支持能源在线监测系统应用的AIOT产品方案 近年来,智慧能源行业受益于国家政策扶持、市场需求拉动和先进技术支撑呈现出了蓬勃发展态势。助推智慧能源发展,打造了支持能源在线监测系统应用的AIOT产品方案。 能源在线监测系统的市场潜力 随着社会经济的飞…

C++笔记---类和对象(中)

1. 类的默认成员函数 默认成员函数就是用户没有显式实现,编译器会自动生成的成员函数称为默认成员函数。 一个类,我们不写的情况下编译器会默认生成以下6个默认成员函数,分别为:构造函数,析构函数,拷贝构…

【Java】Java swing 民宿管理系统 GUI(源码+可视化界面)【独一无二】

👉博__主👈:米码收割机 👉技__能👈:C/Python语言 👉公众号👈:测试开发自动化【获取源码商业合作】 👉荣__誉👈:阿里云博客专家博主、5…

【vulnhub】W1R3S.inc靶机

靶机安装 下载地址:https://download.vulnhub.com/w1r3s/w1r3s.v1.0.1.zip 运行环境:vmware 信息收集 靶机发现IP扫描 nmap 192.168.93.0/24 端口扫描,发现开放21、22、80、3306端口 nmap -A 192.168.93.159 -p- 进行目录扫描 dirsearach -u http…

函数实例讲解(三)

文章目录 常用的三个数学函数1、绝对值函数ABS2、取整数部分INT3、求余数函数MOD 求极值函数max、min1、Max2、Min 附加条件下求平均数1、AVERAGE2、AVERAGEIF3、AVERAGEIFS VLOOKUP与COLUMN1、VLOOKUP2、COLUMN 查找函数LOOKUP1、基础语法2、向量形式3、数组形式 常用的三个数…

Odoo生产执行(MES)系统管理解决方案简介

什么是生产执行管理解决方案? Odoo生产执行管理解决方案可以在统一平台上集成诸如生产调度、产品跟踪、质量控制、设备故障分析、网络报表等管理功能,使用统一的数据库和通过网络联接可以同时为生产部门、质检部门、工艺部门、物流部门等提供车间管理信息…

windows 部署 mindspore GPU 开发环境(WSL)

基础环境 windows 环境: Windows 10 版本:22H2 操作系统版本:22621.2283 WSL 系统 版本:2.2.4.0 Ubuntu-20.04 一、自定义位置安装Ubuntu 确保已经安装 WSL 在微软应用商店搜索时务必输入全名 Ubuntu20.04,并安装…

LLM:SGD、adam

SGD没有一阶和二阶动量。adam是融合了这两种动量。 参考:https://blog.csdn.net/yinyu19950811/article/details/90476956 【十分钟搞明白Adam和AdamW,SGD,Momentum,RMSProp,Adam,AdamW】

【window10/window11】解决任务管理器有进程无法强制结束情况

以管理员身份启动控制台窗体,然后从任务管理器中查询到你要结束的进程名,然后运行以下命令(UniAccessAgent.exe替换成你要结束的进程): wmic process where nameUniAccessAgent.exe delete 此方法可以解决在任务管理…

微软蓝屏事件揭示的网络安全深层问题与未来应对策略

目录 微软蓝屏事件揭示的网络安全深层问题与未来应对策略 一、事件背景 二、事件影响 2.1、跨行业连锁反应 2.2、经济损失和社会混乱 三、揭示的网络安全问题 3.2、软件更新管理与风险评估 3.2、系统复杂性与依赖关系 3.3、网络安全意识与培训 四、未来的网络安全方向…

LSPatch制作内置模块应用软件无需root 教你制作内置应用

前言 LSPatch功能非常强大,它是一款基于LSPosed核心的免Root Xposed框架软件。这意味着用户无需进行手机root操作,即可轻松植入内置Xposed模块,享受更多定制化的功能和体验,比如微某内置模块版等,这为那些不想root手机…

分享一个基于Spring Boot的在线智慧考公学习管理系统(源码、调试、LW、开题、PPT)

💕💕作者:计算机源码社 💕💕个人简介:本人 八年开发经验,擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等,大家有这一块的问题可以一起交流&…