Qt网络编程-简易版UDP组播通信入门Demo(5)

11 篇文章 12 订阅

Qt网络编程-简易版UDP组播通信入门Demo(5)🍳

更多精彩内容
👉个人内容分类汇总 👈
简易版
👉Qt网络编程-简易版TcpClient入门Demo(1)👈
👉Qt网络编程-简易版TcpServer入门Demo(2)👈
👉Qt网络编程-简易版UDP单播通信入门Demo(3)👈
👉Qt网络编程-简易版UDP单播通信入门Demo(4)👈
👉Qt网络编程-简易版UDP组播通信入门Demo(5)👈
👉Qt网络编程-简易版UDP广播通信入门Demo(6)👈
进阶版
👉Qt网络编程-TcpClient入门Demo(1)👈
👉Qt网络编程-TcpServer入门Demo(2)👈

1、概述🥚

使用QUdpSocket实现UDP组播通信功能,十分简易的入门Demo

第一,绝对不意气用事;

第二,绝对不放过任何一个注释;

第三,绝对保证代码的简洁明了。🤘

为了便于学习,在这个Demo里会尽可能简单的实现UDP组播通信功能,尽可能少的引入其它功能,只保留了基本功能,所以可能会有一些bug。

实现功能:

  • 在同一系统下,同一时间可打开多个UDP组播窗口,绑定同一个端口号进行通信;
  • 数据接收功能;
  • 数据发送功能。

2、组播🍚

2.1 什么是组播🍪

  • 组播也可以称之为多播,是 UDP 的特性之一。
  • 组播是主机间一对多的通讯模式,是一种允许一个或多个组播源发送同一报文到多个接收者的技术。
  • 组播源将一份报文发送到特定的组播地址,组播地址不同于单播地址,它并不属于特定某个主机,而是属于一组主机。一个组播地址表示一个群组,需要接收组播报文的接收者都加入这个群组。
  • 广播只能在局域网访问内使用,组播既可以在局域网中使用,也可以用于广域网;
  • 在发送广播消息的时候,连接到局域网的客户端不管想不想都会接收到广播数据,组播可以控制发送端的消息能够被哪些接收端接收,更灵活和人性化。
  • UDP组播是采用的无连接,数据报的连接方式,所以是不可靠的。也就是数据能不能到达接受端和数据到达的顺序都是不能保证的。但是由于UDP不用保证数据 的可靠性,所有数据的传送效率是很快的

2.2 组播地址🍰

  • 组播需要使用组播地址,在 IPv4 中它的范围从 224.0.0.0 到 239.255.255.255,并被划分为局部链接多播地址、预留多播地址和管理权限多播地址三类

    224.0.0.0 ~ 224.0.0.255: 局部链接多播地址:是为路由协议和其它用途保留的地址,只能用于局域网中,路由器是不会转发的地址 224.0.0.0 不能用,是保留地址;
    224.0.1.0 ~ 224.0.1.255: 为用户可用的组播地址(临时组地址),可以用于 Internet 上的;
    224.0.2.0 ~ 238.255.255.255: 用户可用的组播地址(临时组地址),全网范围内有效;
    239.0.0.0 ~ 239.255.255.255: 为本地管理组播地址,仅在特定的本地范围内有效;

2.3 组播优点🧁

  • 提高效率: 降低网络流量、减轻硬件负荷;

  • 优化性能: 减少冗余流量、节省网络带宽、降低网络负载;

  • 分布式应用: 是多点应用成为可能;

  • 组播非常适合一对多的通信模型,只有加入到特定组播组的成员,才会受到组播数据,当存在多个组播组成员时,源无需拷贝多个数据发送,仅需发送一份即可,组播网络设备(运行组播路由协议的网络设备)会根据实际需要转发或拷贝组播数据,实现按需拷贝,按需发送;

  • 数据流只发送给加入该组播组的接收者(组成员),而不需要该数据的设备将不会接收到该组播流量;

  • 相同的组播报文,在一段链路上仅有一份数据,大大提高了网络资源的利用率。

2.4 组播缺点🥧

  • 组播是基于UDP的,采用尽力而为的传输方式;
  • 没有拥塞避免机制;
  • 可能出现报文重复的现象;
  • 可能出现报文失序的现象。

2.5 组播使用场景🍫

  • 组播使用于多接受者期望接受相同流量的场景(聊天群,屏幕共享);
  • 多媒体直播;
  • 培训、联合作业场景的通信;
  • 数据仓库、金融应用(股票);
  • 其他“单到多”数据发布应用。

3、UDP组播通信流程图🥦

  • UDP不同于TCP,不需要区分Server和Cilent,数据发送端和接收端都一样;
    在这里插入图片描述

4、 关键信号🌮

信号说明
readyRead有可读数据时发出此信号

5、 关键函数 🍤

函数名说明
state判断QUdpSocket当前状态,BoundState已绑定本地端口
bind绑定本地IP、端口,需要指定AnyIPv4
joinMulticastGroup加入组播组
writeDatagram发送数据报
receiveDatagram读取数据报
leaveMulticastGroup离开组播组
abort关闭套接字连接(解除绑定的端口号)

6、主要代码🍧

  • 注意:.pro文件里添加QT += network,否则编译失败。
  • .h文件
/******************************************************************************
 * @文件名     simpleudpgroup.h
 * @功能       简易的UDP组播通信Demo,主要:UDP组播不能使用connectToHost绑定地址
 *
 * @开发者     mhf
 * @邮箱       1603291350@qq.com
 * @时间       2022/04/19
 * @备注
 *****************************************************************************/
#ifndef SIMPLEUDPGROUP_H
#define SIMPLEUDPGROUP_H

#include <QWidget>
#include <QUdpSocket>

namespace Ui {
class SimpleUdpGroup;
}

class SimpleUdpGroup : public QWidget
{
    Q_OBJECT

public:
    explicit SimpleUdpGroup(QWidget *parent = nullptr);
    ~SimpleUdpGroup();

private slots:
    void on_readyRead();
    void on_but_connect_clicked();

    void on_but_send_clicked();

private:
    Ui::SimpleUdpGroup *ui;
    QUdpSocket* m_udpSocket = nullptr;         // UDP通信对象
};

#endif // SIMPLEUDPGROUP_H

  • .cpp文件
#include "simpleudpgroup.h"
#include "ui_simpleudpgroup.h"

#include <qnetworkdatagram.h>

SimpleUdpGroup::SimpleUdpGroup(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SimpleUdpGroup)
{
    ui->setupUi(this);

    this->setWindowTitle("简易版UDP组播通信Demo");

    m_udpSocket = new QUdpSocket(this);
    connect(m_udpSocket, &QUdpSocket::readyRead, this, &SimpleUdpGroup::on_readyRead);     // 当有可读数据时发出readyRead信号
}

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

/**
 * @brief 读取UDP数据报
 */
void SimpleUdpGroup::on_readyRead()
{
    QNetworkDatagram datagram = m_udpSocket->receiveDatagram();  // 读取数据,这里需要添加qnetworkdatagram.h头文件
    ui->text_recv->append(datagram.data());                      // 显示读取到的数据
}


/**
 * @brief 开始绑定绑定IP端口,用于接收数据,并加入组播组
 */
void SimpleUdpGroup::on_but_connect_clicked()
{
    if(m_udpSocket->state() != QAbstractSocket::BoundState)                                        // 判断是否绑定绑定端口
    {
        bool ret = m_udpSocket->bind(QHostAddress::AnyIPv4,                                        // 使用组播时这里必须要指定AnyIPv4,不指定将会默认Any,加入组播会失败
                                     ui->spin_groupPort->value(),                                  // 绑定绑定接收数据的端口,一般用组播端口
                                     QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);     // ShareAddress允许一台电脑上多个程序绑定同一个端口,便于测试,但是在windows下需要加上ReuseAddressHint才有效
        if(ret)
        {
            qInfo() << "绑定本地地址成功!";
            ret = m_udpSocket->joinMulticastGroup(QHostAddress(ui->line_groupAddress->text()));           // 加入组播组
            if(ret)
            {
                qInfo() << "加入组播组成功!";
                ui->but_connect->setText("关闭");
            }
            else
            {
                qWarning() << "加入组播组失败!";
            }
        }
        else
        {
            qWarning() << "绑定本地地址失败!";
        }
    }
    else
    {
        bool ret = m_udpSocket->leaveMulticastGroup(QHostAddress(ui->line_groupAddress->text()));
        if(ret)
        {
            qInfo() << "移除组播组成功!";
            m_udpSocket->abort();
            ui->but_connect->setText("打开");
        }
        else
        {
            qWarning() << "移除组播组失败!";
        }
    }
}


/**
 * @brief 发送数据,由于已经绑定了目标IP和目标端口号,在发送数据时就不用指定IP、端口了
 */
void SimpleUdpGroup::on_but_send_clicked()
{
    QString str = ui->text_send->toPlainText();
    qint64 len = m_udpSocket->writeDatagram(str.toUtf8(), QHostAddress(ui->line_groupAddress->text()), ui->spin_groupPort->value());
    qInfo() << QString("发送数据长度:%1").arg(len);
}


7、实现效果🥠

在这里插入图片描述

8、源代码🥮

gitee
github

🤘🤘🤘🤘🤘🤘🤘🤘🤘🤘🤘🤘🤘🤘🤘🤘🤘🤘🤘🤘🤘🤘

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mahuifa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值