Qt(三):udp组播的发送与接收

news/2024/5/18 16:36:53 标签: qt, udp, 开发语言, 组播, 以太网

1. 创建UDP套接字
使用QUdpSocket类创建一个UDP套接字。

    udpSend=new QUdpSocket(this);
    udpRece=new QUdpSocket(this);


2. 绑定套接字
绑定套接字到一个本地地址和端口。可以使用bind()函数来完成。
如果要在组播中发送数据,可以将套接字绑定到一个通配符地址(如QHostAddress::Any)和指定的端口上。

void MainWindow::on_pBt_joinGroup_clicked()
{
    QString IP_Group=ui->lineEdit_groupAddr->text();//获取组播地址
    groupAddr=QHostAddress(IP_Group);
    quint16 groupPort=ui->lineEdit_goupPort->text().toInt();//获取组播端口
    if(udpRece->bind(QHostAddress::AnyIPv4,groupPort,QUdpSocket::ShareAddress)){//绑定地址
        udpRece->joinMulticastGroup(groupAddr);//加入组播
        ui->plainTextEdit->appendPlainText("**加入组播成功");
        ui->plainTextEdit->appendPlainText("**组播IP地址:"+IP_Group);
        ui->plainTextEdit->appendPlainText("**绑定端口:"+QString::number(groupPort));
        ui->pBt_joinGroup->setEnabled(false);
        ui->pBt_exitGroup->setEnabled(true);

    }
}


3. 加入组播
使用joinMulticastGroup()函数将套接字加入到指定的组播组中。
该函数需要指定组播组的地址和接口地址。

udpRece->joinMulticastGroup(groupAddr);//加入组播


4. 发送数据
使用writeDatagram()函数发送组播数据。
需要指定要发送的数据、目标地址(即组播组的地址)和端口号。

//发送组播
void MainWindow::sendUdpMess(){

     quint16 groupPort=ui->lineEdit_goupPort->text().toInt();//获取组播端口
    QString mesage=ui->lineEdit->text();//读取发送信息
    QByteArray sendMess=mesage.toUtf8();//将发送的信息转化为字节流
    udpSend->writeDatagram(sendMess,groupAddr,groupPort);//将待发送信息写入udp通信中
    ui->plainTextEdit->appendPlainText("[发送端:]"+mesage);//发送信息显示

}


5. 接收数据
当套接字收到组播数据时,会发出readyRead()信号。
在槽函数中,可以使用readDatagram()函数来读取接收到的数据报的内容、源地址和端口号。

//接收组播信息
void MainWindow::receUdpMess(){
    while (udpRece->hasPendingDatagrams()){
        QByteArray receData;//创建接收字节流
        QHostAddress peerAddr;//接收地址
        quint16 peerPort;//接收端口
        quint16 size=udpRece->pendingDatagramSize();//读取接收udp数据大小
        receData.resize(size);//重设接收字节流大小
        udpRece->readDatagram(receData.data(),receData.size(),&peerAddr,&peerPort);//读取以太网发送端的udp数据
        QString peer="[From]+"+peerAddr.toString()+":"+QString::number(peerPort)+"]";//读取发送端地址、端口
        ui->plainTextEdit->appendPlainText(peer+receData.data());//将接收内容显示在文本框中
    }
}

完整代码如下:

一、主cpp文件

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

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    udpSend=new QUdpSocket(this);
    udpRece=new QUdpSocket(this);
    udpRece->setSocketOption(QAbstractSocket::MulticastTtlOption,1);
    connect(udpRece,&QUdpSocket::readyRead,this,&MainWindow::receUdpMess);//连接读取udp通信数据
}

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



//接收组播信息
void MainWindow::receUdpMess(){
    while (udpRece->hasPendingDatagrams()){
        QByteArray receData;//创建接收字节流
        QHostAddress peerAddr;//接收地址
        quint16 peerPort;//接收端口
        quint16 size=udpRece->pendingDatagramSize();//读取接收udp数据大小
        receData.resize(size);//重设接收字节流大小
        udpRece->readDatagram(receData.data(),receData.size(),&peerAddr,&peerPort);//读取以太网发送端的udp数据
        QString peer="[From]+"+peerAddr.toString()+":"+QString::number(peerPort)+"]";//读取发送端地址、端口
        ui->plainTextEdit->appendPlainText(peer+receData.data());//将接收内容显示在文本框中
    }
}

//发送组播
void MainWindow::sendUdpMess(){

     quint16 groupPort=ui->lineEdit_goupPort->text().toInt();//获取组播端口
    QString mesage=ui->lineEdit->text();//读取发送信息
    QByteArray sendMess=mesage.toUtf8();//将发送的信息转化为字节流
    udpSend->writeDatagram(sendMess,groupAddr,groupPort);//将待发送信息写入udp通信中
    ui->plainTextEdit->appendPlainText("[发送端:]"+mesage);//发送信息显示

}

//加入组播
void MainWindow::on_pBt_joinGroup_clicked()
{
    QString IP_Group=ui->lineEdit_groupAddr->text();//获取组播地址
    groupAddr=QHostAddress(IP_Group);
    quint16 groupPort=ui->lineEdit_goupPort->text().toInt();//获取组播端口
    if(udpRece->bind(QHostAddress::AnyIPv4,groupPort,QUdpSocket::ShareAddress)){//绑定地址
        udpRece->joinMulticastGroup(groupAddr);//加入组播
        ui->plainTextEdit->appendPlainText("**加入组播成功");
        ui->plainTextEdit->appendPlainText("**组播IP地址:"+IP_Group);
        ui->plainTextEdit->appendPlainText("**绑定端口:"+QString::number(groupPort));
        ui->pBt_joinGroup->setEnabled(false);
        ui->pBt_exitGroup->setEnabled(true);

    }
}

//退出组播
void MainWindow::on_pBt_exitGroup_clicked()
{
    udpRece->leaveMulticastGroup(groupAddr);//退出组播
    udpRece->abort();//解除绑定
    ui->plainTextEdit->appendPlainText("**已退出组播");
    ui->pBt_exitGroup->setEnabled(false);
    ui->pBt_joinGroup->setEnabled(true);
    sendTimer->stop();
}

//清空文本框
void MainWindow::on_pBt_clearText_clicked()
{
    ui->plainTextEdit->clear();
}

//退出
void MainWindow::on_pBt_exit_clicked()
{
    this->close();
}

//发送信息
void MainWindow::on_pushButton_clicked()
{
    sendTimer=new QTimer(this);
    connect(sendTimer,&QTimer::timeout,this,&MainWindow::sendUdpMess);
    sendTimer->start(1000);//一秒发一次
}

二、头文件(.h)

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QUdpSocket>
#include <QTimer>

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_pBt_joinGroup_clicked();

    void on_pBt_exitGroup_clicked();

    void on_pBt_clearText_clicked();

    void on_pBt_exit_clicked();

    void receUdpMess();//接收组播信息

    void sendUdpMess();//发送信息

    void on_pushButton_clicked();

private:

    Ui::MainWindow *ui;
    QUdpSocket *udpRece;
    QUdpSocket *udpSend;
    QHostAddress groupAddr;
    QTimer *sendTimer;

};
#endif // MAINWINDOW_H

运行结果:

源代码放在如下链接中,需要的点击获取:

udp组播发送与接收icon-default.png?t=N7T8https://download.csdn.net/download/weixin_51631044/88692407


http://www.niftyadmin.cn/n/5299774.html

相关文章

(自用)病理学第四章炎症重点知识思维导图和考试真题总结(深大特供)

思维导图部分截图如下&#xff1a; 自己留档用&#xff0c;深大学生特供&#xff0c;其他人想要的画也可以参考一下&#xff0c;以下是笔记原件&#xff1a; https://yvwondo61xn.feishu.cn/mindnotes/B15Pbe1OHm0c9enG1UYcJXPvnLg?fromfrom_copylink 画板原件&#xff1a;…

C++初阶------------------入门C++

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

Linux Debian12安装和使用ImageMagick图像处理工具 常见图片png、jpg格式转webp格式

一、ImageMagick简介 ImageMagick是一套功能强大、稳定而且免费的工具集和开发包。可以用来读、写和图像格式转换&#xff0c;可以处理超过100种图像格式&#xff0c;包括流行的TIFF, JPEG, GIF, PNG, PDF以及PhotoCD等格式。对图片的操作&#xff0c;即可以通过命令行进行&am…

计算机基础面试题 |03.精选计算机基础面试题

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

【DevOps】搭建 项目管理软件 禅道

文章目录 1、简介2、环境要求3、搭建部署环境3.1. 安装Apache服务3.2. 安装PHP环境&#xff08;以php7.0为例 &#xff09;3.3. 安装MySQL服务 4、搭建禅道4.1、下载解压4.2、 配置4.2.1、 启动4.2.2、自启动4.2.3、确认是否开机启动 5、成功安装 1、简介 禅道是国产开源项目管…

100天精通Python(实用脚本篇)——第111天:批量将PDF转Word文档(附上脚本代码)

文章目录 专栏导读1. 将PDF转Word文档需求2. 模块安装3. 模块介绍4. 注意事项5. 完整代码实现6. 运行结果书籍推荐 专栏导读 &#x1f525;&#x1f525;本文已收录于《100天精通Python从入门到就业》&#xff1a;本专栏专门针对零基础和需要进阶提升的同学所准备的一套完整教…

c# 并行处理

以下是一个使用 C# 并行处理来读取大量小文件的例子&#xff0c;这个例子中我们使用 Parallel.ForEach 方法并结合 File.ReadAllLines 来提高读取速度&#xff1a; using System; using System.Collections.Concurrent; using System.IO; using System.Linq;class Program {st…

实战入门 K8s剩下三个模块

1.Label Label是kubernetes系统中的一个重要概念。它的作用就是在资源上添加标识&#xff0c;用来对它们进行区分和选择。 Label的特点&#xff1a; 一个Label会以key/value键值对的形式附加到各种对象上&#xff0c;如Node、Pod、Service等等 一个资源对象可以定义任意数量…