当前位置: 首页 > news >正文

C++ Qt开发:QUdpSocket实现组播通信

Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用QUdpSocket组件实现基于UDP的组播通信。

组播是一种一对多的通信方式,允许一个发送者将数据报文发送到多个接收者,这些接收者通过共享相同的组播IP地址进行通信。在设置组播地址时需要注意,该范围被限制在239.0.0.0~239.255.255.255以内,这是预留给组播的地址范围。

setSocketOption 设置套接字

在Qt中使用组播,首先需要调用setSocketOption函数,该函数是 QUdpSocket 类的成员函数,用于设置套接字的选项。

该函数原型如下:

bool QUdpSocket::setSocketOption(QAbstractSocket::SocketOption option, const QVariant & value
)
  • option:要设置的套接字选项,这里应该是 QAbstractSocket::MulticastTtlOption,表示设置多播 TTL 选项。
  • value:选项的值,这里应该是 TTL 的值。在 IPv4 中,TTL 是一个 8 位的字段,表示数据报在网络中允许经过的最大路由器数量。通常情况下,TTL 值越大,数据报能够传播的范围就越广。

函数返回一个 bool 类型的值,表示是否成功设置了选项。如果设置成功,返回 true,否则返回 false

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);udpSocket=new QUdpSocket(this);// 设置为多播udpSocket->setSocketOption(QAbstractSocket::MulticastTtlOption,1);
}

bind 绑定套接字地址

接着就是对特定端口的绑定,绑定端口可以通过调用bind函数,该函数用于将 QUdpSocket 绑定到指定的本地地址和端口,并设置特定的绑定选项。

在我们的课件中,使用 bind()QUdpSocket 绑定到 IPv4 的任意地址,并指定了一个组播(Multicast)端口,同时设置了共享地址(ShareAddress)选项。

该函数原型如下:

void QUdpSocket::bind(const QHostAddress & address, quint16 port, BindMode mode = DefaultForPlatform
)
  • address:要绑定的本地地址,这里使用 QHostAddress::AnyIPv4 表示绑定到 IPv4 的任意地址。
  • port:要绑定的本地端口号,这里应该是组播端口号。
  • mode:绑定模式,指定套接字的行为。这里使用 QUdpSocket::ShareAddress 表示共享地址选项,它允许多个套接字同时绑定到相同的地址和端口。

函数将 QUdpSocket 绑定到指定的地址和端口,并且允许多个套接字同时共享相同的地址和端口。

joinMulticastGroup 加入组播

joinMulticastGroup() 函数是 QUdpSocket 类的成员函数,用于将 QUdpSocket 加入指定的多播组。

该函数原型如下:

bool QUdpSocket::joinMulticastGroup(const QHostAddress & groupAddress, const QNetworkInterface & iface = QNetworkInterface()
)
  • groupAddress:要加入的多播组的组播地址。
  • iface:要加入多播组的网络接口。默认情况下,会选择默认的网络接口。

函数返回一个 bool 类型的值,表示是否成功加入了多播组。如果成功加入多播组,返回 true;否则返回 false。通过调用 joinMulticastGroup() 函数,QUdpSocket 将成为指定多播组的成员,并能够接收该多播组发送的数据报。

// 开始组播
void MainWindow::on_pushButton_start_clicked()
{// 获取IPQString IP= ui->lineEdit_address->text();groupAddress=QHostAddress(IP);// 获取端口quint16 groupPort = ui->lineEdit_port->text().toUInt();// 绑定端口if (udpSocket->bind(QHostAddress::AnyIPv4, groupPort, QUdpSocket::ShareAddress)){// 加入组播udpSocket->joinMulticastGroup(groupAddress);ui->plainTextEdit->appendPlainText("[*] 加入组播 " + IP + ":" + QString::number(groupPort));}
}

leaveMulticastGroup 退出组播

leaveMulticastGroup() 函数用于将 QUdpSocket 从指定的多播组中移除。通过调用该函数,QUdpSocket 将不再是指定多播组的成员,不再接收该多播组发送的数据报。

该函数原型如下:

bool QUdpSocket::leaveMulticastGroup(const QHostAddress & groupAddress, const QNetworkInterface & iface = QNetworkInterface()
)
  • groupAddress:要离开的多播组的组播地址。
  • iface:要离开多播组的网络接口。默认情况下,会选择默认的网络接口。

函数返回一个 bool 类型的值,表示是否成功离开了多播组。如果成功离开多播组,返回 true;否则返回 false

// 关闭组播
void MainWindow::on_pushButton_stop_clicked()
{// 退出组播udpSocket->leaveMulticastGroup(groupAddress);udpSocket->abort();ui->plainTextEdit->appendPlainText("[-] 退出组播");
}

writeDatagram 发送数据报

writeDatagram() 函数是 QUdpSocket 类的成员函数,用于发送数据报到指定的多播组。通过调用该函数,可以将数据报发送到指定的多播组和端口,让其他成员接收到该数据报。

其函数原型如下:

qint64 QUdpSocket::writeDatagram(const QByteArray & datagram, const QHostAddress & groupAddress, quint16 port
)
  • datagram:要发送的数据报的内容,通常是一个 QByteArray 对象。
  • groupAddress:要发送到的多播组的组播地址。
  • port:要发送到的多播组的端口号。

函数返回一个 qint64 类型的值,表示实际发送的字节数。如果发送成功,返回发送的字节数;否则返回 -1。

// 发送组播消息
void MainWindow::on_pushButton_send_clicked()
{quint16 groupPort = ui->lineEdit_port->text().toUInt();QString msg=ui->lineEdit_msg->text();QByteArray datagram=msg.toUtf8();udpSocket->writeDatagram(datagram,groupAddress,groupPort);
}

readDatagram 接收数据报

readDatagram() 函数是 QUdpSocket 类的成员函数,用于从套接字中读取数据报,并将其存储到指定的缓冲区中。通常情况下,可以使用这个函数来接收来自其他主机的数据报。通过使用该函数可从套接字中读取数据报,并获取数据报的源地址和端口号。

其函数原型如下:

qint64 QUdpSocket::readDatagram(char * data, qint64 maxSize, QHostAddress * address = nullptr, quint16 * port = nullptr
)
  • data:指向用于存储接收数据的缓冲区的指针。
  • maxSize:缓冲区的最大大小,即最多可以接收的字节数。
  • address:指向用于存储发送数据报的源地址的 QHostAddress 对象的指针。
  • port:指向用于存储发送数据报的源端口号的 quint16 类型的指针。

该函数返回一个 qint64 类型的值,表示实际接收的字节数。如果接收成功,返回接收的字节数;否则返回 -1。

// 读取数据报
void MainWindow::onSocketReadyRead()
{while(udpSocket->hasPendingDatagrams()){QByteArray datagram;datagram.resize(udpSocket->pendingDatagramSize());QHostAddress peerAddr;quint16 peerPort;udpSocket->readDatagram(datagram.data(),datagram.size(),&peerAddr,&peerPort);QString str=datagram.data();QString peer="[从 "+peerAddr.toString()+":"+QString::number(peerPort)+" 发送] ";ui->plainTextEdit->appendPlainText(peer+str);}
}

读者可自行运行课件程序,并在多台电脑中配置相同网段,当点击发送消息时所有同网段的程序都将收到广播,如下图所示;

相关文章:

C++ Qt开发:QUdpSocket实现组播通信

Qt 是一个跨平台C图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用QUdpSocket组件实现基于UDP的组播通信…...

excel 表中有图片并在筛选特定行时,只显示该行的图片

建议:选中excel 表中某张图片,CtrlA,选中所有图片。再右键,在菜单中选设置对象格式 在属性里按下图设置, 生效之后,筛选某个产品的时候,就不会显示其他的不符合筛选条件的产品的图片了。...

【QA】MySQL多表查询详解

文章目录 前言关系型数据库中数据表之间的关系数据准备数据内容表间关系 基础查询 | 全部查询多表查询分类1 | 连接查询内连接外连接 | 左外连接外连接 | 右外连接自连接 | 自连接自连接 | 联合查询 分类2 | 子查询返回结果分类 | 标量子查询返回结果分类 | 列子查询返回结果分…...

【Entity Framework】 EF三种开发模式

【Entity Framework】 EF三种开发模式 文章目录 【Entity Framework】 EF三种开发模式一、概述二、DataBase First2.1 DataBase First简介2.2 DataBase First应用步骤2.3 DataBase First总结 三、Model First3.1 Model First简介3.2 Model First实现步骤 四、Code First4.1 Cod…...

数据分析---SQL(5)

目录 子查询单行子查询多行子查询视图(View)创建视图使用视图更新视图视图的优缺点存储过程存储过程的创建存储过程的参数存储过程的优缺点可能导致性能问题避免存储过程引入性能问题子查询 子查询是指在一个查询语句中嵌套另一个查询语句,内部的查询语句称为子查询,外部的…...

《剑指 Offer》专项突破版 - 面试题 93 : 最长斐波那契数列(C++ 实现)

题目链接:最长斐波那契数列 题目: 输入一个没有重复数字的单调递增的数组,数组中至少有 3 个数字,请问数组中最长的斐波那契数列的长度是多少?例如,如果输入的数组是 [1, 2, 3, 4, 5, 6, 7, 8]&#xff0…...

代码随想录算法训练营第五十五天|583. 两个字符串的删除操作、72. 编辑距离

583. 两个字符串的删除操作 刷题https://leetcode.cn/problems/delete-operation-for-two-strings/description/文章讲解https://programmercarl.com/0583.%E4%B8%A4%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E5%88%A0%E9%99%A4%E6%93%8D%E4%BD%9C.html视频讲解https://…...

StringRedisTemplate Autowired注入为空解决

如下注入方式报空指针异常: java.lang.NullPointerException: null Autowiredprivate StringRedisTemplate redisTemplate; 解决办法:查看该类上有没有加注解,如Component等,没加的话加上。 还有一种是在工具类中使用,…...

c语言:文件操作

1. 为什么使⽤⽂件? 如果没有⽂件,我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失 了,等再次运⾏程序,是看不到上次程序的数据的,如果要将数据进⾏持久…...

C#事件实例详解

一、什么是事件? 在C#中,事件(event)是一种特殊的类成员,它允许类或对象通知其他类或对象发生了某些事情。 从语法上看,事件的声明类似于字段,但它们在功能和行为上有一些重要的区别。 从技术角度来说,事件实际上是一个封装了事件订阅和取消订阅功能的委托字段。…...

零基础机器学习(3)之机器学习的一般过程

文章目录 一、机器学习一般过程1.数据获取2.特征提取3.数据预处理①去除唯一属性②缺失值处理A. 均值插补法B. 同类均值插补法 ③重复值处理④异常值⑤数据定量化 4.数据标准化①min-max标准化(归一化)②z-score标准化(规范化) 5.…...

用java做一个双色球彩票系统

代码如下&#xff1a; import java.util.Random; public class HelloWorld{public static void main(String[] args){//1、生成中奖号码 int[] arrcreateNumber();for (int i 0;i<arr.length;i) {System.out.print(arr[i]" ");}}public static int[] createNu…...

某对象存储元数据集群改造流水账

软件产品&#xff1a;某厂商提供的不便具名的对象存储产品&#xff0c;核心底层技术源自HDFS和Amazon S3&#xff0c;元数据集群采用了基于MongoDB的NOSQL数据库产品和MySQL数据库产品相结合。 该产品的元数据逻辑示意图如下&#xff1a; 业务集群现状&#xff1a;当前第3期建…...

前端理论总结(js)——filter、foearch、for in 、for of 、for的区别以及返回值

Filter&#xff1a; 用途&#xff1a;用于筛选数组中符合条件的元素&#xff0c;返回一个新数组。 返回值&#xff1a;返回一个新数组&#xff0c;包含经过筛选的元素。 Foreach&#xff1a; 用途&#xff1a;遍历数组中的每个元素&#xff0c;执行回调函数。 返回值&#x…...

【JavaEE初阶系列】——多线程案例一——单例模式 (“饿汉模式“和“懒汉模式“以及解决线程安全问题)

目录 &#x1f6a9;单例模式 &#x1f388;饿汉模式 &#x1f388;懒汉模式 ❗线程安全问题 &#x1f4dd;加锁 &#x1f4dd;执行效率提高 &#x1f4dd;指令重排序 &#x1f36d;总结 单例模式&#xff0c;非常经典的设计模式&#xff0c;也是一个重要的学科&#x…...

革新水库大坝监测:传统软件与云平台之比较

在水库大坝的监测管理领域&#xff0c;传统监测软件虽然曾发挥了重要作用&#xff0c;但在多方面显示出了其局限性。传统解决方案通常伴随着高昂的运维成本&#xff0c;需要大量的硬件支持和人员维护&#xff0c;且软件整合和升级困难&#xff0c;限制了其灵活性和扩展性。 点击…...

C++模版(基础)

目录 C泛型编程思想 C模版 模版介绍 模版使用 函数模版 函数模版基础语法 函数模版原理 函数模版实例化 模版参数匹配规则 类模版 类模版基础语法 C泛型编程思想 泛型编程&#xff1a;编写与类型无关的通用代码&#xff0c;是代码复用的一种手段。 模板是泛型编程…...

MySQL驱动Add Batch优化实现

MySQL 驱动 Add Batch 优化实现 MySQL 驱动会在 JDBC URL 添加 rewriteBatchedStatements 参数时&#xff0c;对 batch 操作进行优化。本文测试各种参数组合的行为&#xff0c;并结合驱动代码简单分析。 batch参数组合行为 useServerPrepStmts 参数 PreparedStatement psmt…...

手撕算法-数组中的第K个最大元素

描述 分析 使用小根堆&#xff0c;堆元素控制在k个&#xff0c;遍历数组构建堆&#xff0c;最后堆顶就是第K个最大的元素。 代码 class Solution {public int findKthLargest(int[] nums, int k) {// 小根堆PriorityQueue<Integer> queue new PriorityQueue<>…...

【vue】computed和watch的区别和应用场景

Computed 和 Watch 是 Vue.js 中用于监视数据变化的两个不同特性&#xff0c;它们各自有不同的应用场景和功能。 Computed&#xff1a; 计算属性&#xff08;Computed properties&#xff09;用于声明基于其他数据属性的计算值。它具有缓存功能&#xff0c;只有在依赖的数…...

超冷原子吸收成像的深度学习优化方法

1. 超冷原子吸收图像分析的技术挑战在超冷原子实验中&#xff0c;原子云的空间分布信息是理解量子态的关键指标。吸收成像技术通过测量原子云对共振激光的吸收情况&#xff0c;能够非破坏性地获取这一信息。典型的吸收成像过程需要采集三帧图像&#xff1a;包含原子的图像&…...

《论三生原理》对《周易》《道德经》的一次根本性重写?

AI辅助创作&#xff1a;一、关于《周易》来历根源的推断属于文化创新实验&#xff0c;是对《周易》来历、性质、底层逻辑的一次根本性重写&#xff1f;《论三生原理》关于《周易》来历根源的推断&#xff0c;确实属于一次大胆的文化创新实验&#xff0c;并且是对《周易》的来历…...

08-系统技术架构师必备——分布式系统理论与数据一致性

关键词:分布式系统、CAP定理、BASE理论、Paxos、Raft、分布式事务、TCC、Saga、一致性算法 分布式系统 CAP定理 分布式事务 一致性算法 Paxos Raft TCC Saga 系统技术架构师必备——分布式系统理论与数据一致性 摘要 分布式系统是系统技术架构师必须跨越的"分水岭"…...

回归模型.

...

ThingsVis v1.1.15 版本更新:补齐嵌入与运维体验短板,多场景集成更可靠

ThingsVis v1.1.15&#xff1a;嵌入与运维体验的全面升级ThingsVis v1.1.15 版本以 ThingsVis 嵌入能力和设备详情页体验为核心进行更新。在 ThingsVis 嵌入方面&#xff0c;支持全屏、自动播放、剪贴板写入权限&#xff0c;修复 iframe 无法全屏问题&#xff1b;在设备详情页&…...

AlphaStar强化学习工程范式:从星际争霸到工业决策

1. 这不是“下棋”的升级版&#xff1a;AlphaStar 的强化学习到底在学什么&#xff1f; 很多人第一次听说 AlphaStar&#xff0c;第一反应是&#xff1a;“哦&#xff0c;又一个打败人类的AI&#xff0c;跟 AlphaGo 差不多吧&#xff1f;”——这个理解偏差非常典型&#xff0…...

基于首届中国互联网数据挖掘竞赛数据集的行为相似网络分析

在互联网行为分析中&#xff0c;“社交网络分析”不一定只能依赖好友、关注、私信或转发关系。很多时候&#xff0c;数据里并没有显式的社交边&#xff0c;但用户的网页访问、应用使用、停留时长和活跃节奏&#xff0c;本身就能反映出相似的兴趣圈层。 本项目中的“社交网络分析…...

井下无信号密闭空间:UWB基站断联失效,无感定位纯视觉独立解算

井下无信号密闭空间&#xff1a;UWB基站断联失效&#xff0c;无感定位纯视觉独立解算矿山井下巷道、采掘工作面、密闭峒室等区域&#xff0c;属于典型无外源通信、信号隔绝的密闭作业空间。数字孪生与视频孪生技术逐步下沉矿山安全生产领域&#xff0c;镜像视界浙江科技有限公司…...

AI赋能百业,从城市治理到智能家居,这些应用场景让你大开眼界!

文章深入探讨了人工智能在各个领域的创新应用&#xff0c;包括城市治理、医疗、金融、教育、交通出行、零售电商、制造、能源、农业、智能家居、娱乐传媒、文化旅游等。通过具体的案例和技术手段&#xff0c;展示了AI如何提升效率、优化决策、改善生活质量。例如&#xff0c;成…...

2026大模型技术全景:从“写代码“到“做工程“

2026大模型技术全景&#xff1a;从"写代码"到"做工程"大模型技术正从"炫酷玩具"迈向"核心生产力工具"。本文从技术进展、关键方向、应用场景到未来趋势&#xff0c;全面梳理2026年大模型技术全景。一、引言 2026年&#xff0c;大模型技…...