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

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

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

文章目录
  • Qt网络编程-简易版UDP组播通信入门Demo(5)🍳
    • 1、概述🥚
    • 2、组播🍚
      • 2.1 什么是组播🍪
      • 2.2 组播地址🍰
      • 2.3 组播优点🧁
      • 2.4 组播缺点🥧
      • 2.5 组播使用场景🍫
    • 3、UDP组播通信流程图🥦
    • 4、 关键信号🌮
    • 5、 关键函数 🍤
    • 6、主要代码🍧
    • 7、实现效果🥠
    • 8、源代码🥮

更多精彩内容
👉个人内容分类汇总 👈
简易版
👉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
 * @邮箱       [email protected]
 * @时间       2022/04/19
 * @备注
 *****************************************************************************/
#ifndef SIMPLEUDPGROUP_H
#define SIMPLEUDPGROUP_H

#include 
#include 

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 

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

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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/langs/738936.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-28
下一篇 2022-04-28

发表评论

登录后才能评论

评论列表(0条)

保存