【Qt】Qt 网络 | UDP Socket

文章目录

  • 核心API
  • 代码示例
    • 服务器
    • 客户端

要使用 Qt 网络编程,需要在项目中的 .pro 文件中添加 network 模块
在这里插入图片描述

核心API

Qt 的 UDP Socket 主要的类有两个 QUdpSocketQNetworkDatagram
因为是 UDP 是面向数据报的,QNetworkDatagram 就是对 数据报的封装,内容包括:对端发送的数据,对端的 IP 和 端口号

QUdpSocket 表示一个 UDP 的 socket 文件

名称类型说明对标原生API
bind(const QHostAddress &address, quint16 port = 0)方法绑定指定的 IP地址 和 端口号bind
receiveDatagram()方法返回 QNetworkDatagram 读取一个 UDP 数据报recvfrom
writeDatagram(const QNetworkDatagram &datagram)方法发送一个 UDP 数据报sendto
writeDatagram(const char *data, qint64 size, const HostAddress &address, quint16 port)方法data是要发送的数据,size是数据的长度,address是目标 IP地址,port是目标端口号sendto
readyRead信号在收到数据并准备就绪后触发类似于 IO 多路复用的通知机制

QNetworkDatagram 表示一个 UDP 数据报

名称类型说明对标原生API
QNetworkDatagram(const QByteArray &data, const QHostAddress &destinationAddress = QHostAddress(), quint16 port = 0)构造函数通过 QByteArray,目标 IP地址,目标端口号构造一个 UDP 数据报,通常用于发送数据
data()方法获取数据报内部持有的数据,返回 QByteArray
senderAddress()方法获取数据报中包含的对端的IP地址recvfrom 包含了该功能
senderPort()方法获取数据报中包含的对端的端口号recvfrom 包含了该功能

代码示例

通过模拟 客户服务器的UDP通信 熟悉上述方法使用
客户端通过输入栏获取数据,点击按钮发送给服务端
服务端接受客户端数据,并返回相同数据,验证通信无误

服务器

  1. 创建界面,包含一个 QListWidget 用来显示消息
    在这里插入图片描述
  2. 创建 QUdpSocket 成员,修改 widget.h
class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
//槽函数
public slots:void handleRequest();//处理客户端请求
private:QString process(const QString &request);//业务处理逻辑
private:Ui::Widget *ui;QUdpSocket *socket;//套接字
};
  1. 编写 widget.cpp,实现相关方法

因为 UDP 是无连接的,绑定端口号后就可以接受数据了,所以要先对 readReady信号连接槽函数
逻辑如下:1. 设置窗口标题 2. 创建套接字 3. 连接信号槽 4. 绑定端口号

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//1. 设置窗口标题this->setWindowTitle("服务端");//2. 创建套接字socket = new QUdpSocket(this);//UDP绑定完就开启服务了,所以需要先连接信号槽//3. 连接信号槽connect(socket, &QUdpSocket::readyRead, this, &Widget::handleRequest);//4. 绑定,服务端绑定任意IP,端口号指定为9090bool ret = socket->bind(QHostAddress::Any, 9090);if(!ret){QMessageBox::critical(this, "错误", "绑定套接字失败");return;}}

编写 readReady 对应槽函数
逻辑如下:1. 获取用户数据报 2. 提取其中数据 3. 业务处理 4. 返回响应

void Widget::handleRequest()
{//1. 获取用户数据报const QNetworkDatagram requestDatagram = socket->receiveDatagram();//2. 提取其中数据QString request = requestDatagram.data();//3. 业务处理逻辑QString responce = process(request);//4. 记录客户端数据QString log = "[" + requestDatagram.senderAddress().toString() + ":" + QString::number(requestDatagram.senderPort())+ "]  request:" + request + "  responce:" + responce;ui->listWidget->addItem(log);//5. 返回响应QNetworkDatagram responceDatagram(responce.toUtf8(), requestDatagram.senderAddress(), requestDatagram.senderPort());socket->writeDatagram(responceDatagram);
}

此处服务器的业务处理只是简单的回显数据

QString Widget::process(const QString &request)
{return request;
}

客户端

  1. 创建界面。包含 一个 QLineEditQPushButtonQListWidget
    通过布局管理器搭配,规范界面
    在这里插入图片描述
  2. 声明全局常量:服务端的 IP地址端口号
#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 9090
  1. 创建 QUdpSocket 成员,修改 widget.h,定义成员
class Widget : public QWidget
{Q_OBJECT
public:Widget(QWidget *parent = nullptr);~Widget();
private slots://按钮点击槽函数void on_pushButton_clicked();//客户端业务处理逻辑void handleRequest();
private:Ui::Widget *ui;QUdpSocket *socket;
};
  1. 修改 widget.cpp,初始化 socket
    客户端不需要绑定端口号
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->pushButton->setShortcut(QKeySequence(Qt::Key_Return));//设置窗口标题this->setWindowTitle("客户端");//创建套接字socket = new QUdpSocket(this);//连接信号槽connect(socket, &QUdpSocket::readyRead, this, &Widget::handleRequest);
}

按钮点击槽函数
逻辑如下:1. 获取输入栏文本 2. 记录发送信息 3. 将消息发送给服务端 4. 清空输入栏

void Widget::on_pushButton_clicked()
{//1. 获取输入栏的文本QString text = ui->lineEdit->text();QNetworkDatagram requestDatagram(text.toUtf8(), QHostAddress(SERVER_IP), SERVER_PORT);//2. 记录发送信息QString message = "发送:" + text;ui->listWidget->addItem(message);//3. 将消息发送给服务端socket->writeDatagram(requestDatagram);//4. 将输入栏清空ui->lineEdit->clear();
}

客户端业务处理函数

void Widget::handleRequest()
{//1. 获取服务端返回的数据报QNetworkDatagram responceDatagram = socket->receiveDatagram();QString responce = responceDatagram.data();//2. 显示消息ui->listWidget->addItem("接收:" + responce);
}

运行结果如下:
在这里插入图片描述

结束语
感谢你的阅读
如果觉得本篇文章对你有所帮助的话,不妨点个赞支持一下博主,拜托啦,这对我真的很重要。
在这里插入图片描述

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

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

相关文章

ChatGPT写文章时,如何去除生硬的Ai味?

仅做分享,侵删 在使用AI进行写作时,常常会发现生成的文章带有明显的“机器味”,一眼就能看出是由AI生成的。这是许多希望借助AI进行自媒体创作的小伙伴们面临的一个主要问题。AI生成的文章往往过于书面化,缺乏人情味,导…

Xmind2024去除VIP会员解锁版

XMind 2024:让思维导图变得有趣又高效 🌟新功能大揭秘🌟 亲爱的小仙女们,今天我要给你们安利一款神奇的软件——XMind 2024!这不仅仅是一款普通的思维导图软件,它可是集美貌与智慧于一身的超级助手哦&…

【学习笔记】 陈强-机器学习-Python-Ch13 提升法

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-…

3674B/C/D/E/F/G矢量网络分析仪

3674B/C/D/E/F/G矢量网络分析仪 <<<3674系列矢量网络分析仪>>> Ceyear 3674系列矢量网络分析仪是技术创新的巅峰之作&#xff0c;可以轻松应对半导体芯片测试、材料测试、天线测试、高速线缆测试、微波部组件测试等带来的严峻挑战。出色的射频特性、灵活的硬…

提升多跳问答中的语言模型知识编辑能力

人工智能咨询培训老师叶梓 转载标明出处 大模型在静态知识库的更新上存在局限&#xff0c;特别是在面对需要多步骤推理的多跳问题时&#xff0c;难以提供准确和最新的回答。为了解决这一问题&#xff0c;来自美国佐治亚大学、纽约大学、莱斯大学、北卡罗来纳州立大学等机构的研…

案例-KVM+GFS分布式存储系统构建KVM高可用(虚拟化实战)

NFS GlusterFS 基于共享存储 采用GFS做共享存储&#xff1b; 实验环境&#xff1a;101 102 103 104 做gfs集群&#xff1b;201 202做虚拟机&#xff1b; 同步一下会话&#xff1b; 为了方便使用主机名进行通信&#xff0c;修改hosts文件&#xff1b; 为了使用GlusterFS的仓库…

机器学习引领未来:赋能精准高效的图像识别技术革新

图像识别技术近年来取得了显著进展,深刻地改变了各行各业。机器学习,特别是深度学习的突破,推动了这一领域的技术革新。本文将深入探讨机器学习如何赋能图像识别技术,从基础理论到前沿进展,再到实际应用与挑战展望,为您全面呈现这一领域的最新动态和未来趋势。 1. 引言 …

Python进阶07-高级语法

零、文章目录 Python进阶07-高级语法 1、with语句 &#xff08;1&#xff09;文件操作 文件使用完后必须关闭&#xff0c;因为文件对象会占用操作系统的资源&#xff0c;并且操作系统同一时间能打开的文件数量也是有限的 # 第一步&#xff1a;打开文件 f open(python.txt…

CAS理解和说明

目录 1.CAS是什么? 2.CAS的应用场景 2.1 实现原子类 2.2 实现自旋锁 3.CAS的典型问题:ABA问题 1.CAS是什么? CAS:全称compare and swap(比较并交换) 我们假设内存中的原始数据V&#xff0c;旧的预期值A&#xff0c;需要修改的新值B 1.比较A与V是否相等&#xff08;比较…

Spring6梳理6——依赖注入之Setter注入

以上笔记来源&#xff1a; 尚硅谷Spring零基础入门到进阶&#xff0c;一套搞定spring6全套视频教程&#xff08;源码级讲解&#xff09;https://www.bilibili.com/video/BV1kR4y1b7Qc 目录 一、引言 二、Java方法初始化过程 2.1 set方法及构造器方法实现Book对象初始化 三…

QT实战项目之音乐播放器

项目效果演示 myMusicShow 项目概述 在本QT音乐播放器实战项目中&#xff0c;开发环境使用的是QT Creator5.14版本。该项目实现了音乐播放器的基本功能&#xff0c;例如开始播放、停止播放、下一首播放、上一首播放、调节音量、调节倍速、设置音乐播放模式等。同时还具备搜索功…

C语言:常用技巧及误用

一、字符串存储在数组中 int main() {char* arr[7] {"xiaoming","zhangsan","李四"};printf("%s\n", arr[0]);printf("%s\n", arr[2]);return 0; } 二、scanf()函数用法 2.1 scanf()输入字符串 int main() {char arr[10…

jquery下载的例子如何应用到vue中

参考测试圈相亲平台开发流程&#xff08;4&#xff09;&#xff1a;选个漂亮的首页 (qq.com) 下载的文件夹解压到v_love项目的pubilc下的static文件夹内&#xff0c;这里放的都是我们的静态资源。 打开文件夹内的index.html&#xff0c;我们先确定下它是不是我们要的东西&…

多目标应用:四种多目标优化算法(NSGA2、NSPSO、NSDBO、NSCOA)求解柔性作业车间调度问题(FJSP),MATLAB代码

一、柔性作业车间调度问题 柔性作业车间调度问题(Flexible Job Scheduling Problem, FJSP) 的描述如下&#xff1a;n个工件 { J , J 2 , . . , J n } \{J,J_2,..,J_n\} {J,J2​,..,Jn​}要在 m m m 台机器 { M 1 , M 2 , . . , M m } \{M_1,M_2,..,M_m\} {M1​,M2​,..,Mm​} …

做了SEO为何效果平平无奇?

SEO&#xff08;Search Engine Optimization&#xff09;即搜索引擎优化&#xff0c;指在不同的搜索引擎中&#xff0c;按照相应的规则与机制提高网站在特定的搜索引擎中的自然排名。作为对产品和服务进行数字宣传营销的重要手段&#xff0c;SEO已然成为各企业提高网站曝光和流…

Ubuntu 24.04 安装 英特尔工具包 Intel® Toolkits

目录 1.采用用户界面 GUI 安装英特尔基本工具包 Intel oneAPI Base Toolkit 1.1 下载离线英特尔基本工具包 1.2 安装英特尔基本工具包 1.3 英特尔基本工具包 Intel oneAPI Base Toolkit 环境设置 2.安装英特尔高性能计算工具包 Intel HPC Toolkit 2.1 下载离线英特尔高性…

[MOCO v3] An Empirical Study of Training Self-Supervised Vision Transformers

1、目的 探索基于contrastive/Siamese范式&#xff08;而非masked auto-encoding范式&#xff09;和ViT结构&#xff08;而非卷积网络&#xff09;的自监督学习 2、方法 MoCo v3 ​​​​​​​ 1&#xff09;random data augmentation 2&#xff09;query encoder &a…

Java笔试面试题AI答之正则表达式(3)

文章目录 13. 简述Java String支持哪几种使用正则表达式的方法&#xff1f;14. 请列举常见校验数字的表达式 &#xff1f;15. 请列举常见校验字符的表达式 &#xff1f;1. 汉字2. 英文和数字3. 特定长度的字符串4. 由26个英文字母组成的字符串5. 由数字和26个英文字母组成的字符…

【电池专题】软包电池封装工序

铝塑膜成型工序冲坑 铝塑膜成型工序,软包电芯可以根据客户的需求设计成不同的尺寸,当外形尺寸设计好后,就需要开具相应的模具,使铝塑膜成型。 成型工序也叫作冲坑,顾名思义,就是用成型模具在加热的情况下,在铝塑膜上冲出一个能够装卷芯的坑,具体的见下图。 …

「Python程序设计」循环控制:for和while循环语句

​我们在实际业务&#xff0c;或者是实际问题&#xff0c;进行数据分析处理的过程中&#xff0c;往往需要对数据集进行处理。 从程序设计的角度来看&#xff0c;一维数组&#xff0c;代表了同一数据类型的相关数据。二维数组&#xff0c;相当于我们excel中的表格&#xff0c;可…