• 【Qt】Qt 网络编程——UDP单播通信


    UDP单播通信概述

    UDP单播通信流程图

    关键信号

    关键函数

    五级标题
    六级标题

    UDP单播通信概述

    • UDP没有所谓的服务器与客户端,只需双方绑定对方的Ip和端口号即可
    • 绑定对方IP、端口是用于发送数据
    • 绑定本地端口是便于对方发送数据
    • 如果没有绑定本地端口,则会自动分配一个端口号,并不影响通信

    UDP单播通信流程图

    在这里插入图片描述

    关键信号

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

    关键函数

    函数名说明
    writeDatagram发送数据报
    readDatagram读取数据报
    bind绑定本地IP、端口

    主要代码

    在.pro文件里添加QT += network,否则编译失败。

    • .h文件
    /******************************************************************************
     * @文件名    udpSimulationClient.h
     * @功能       简易的UDP通信功能Demo,第一种实现方式,传统UDP通信方式。
     *
     * @开发者    
     * @邮箱       
     * @时间       2022/06/24
     * @备注
     *****************************************************************************/
    
    #pragma once
    
    #include <QtWidgets/QMainWindow>
    #include "ui_udpSimulationClient.h"
    #include <qudpsocket.h>
    #include < QTimer>
    
    class udpSimulationClient : public QMainWindow
    {
        Q_OBJECT
    
    public:
    
        udpSimulationClient(QWidget *parent = nullptr);
        ~udpSimulationClient();
    
    private slots:
    
        void on_pushButton_clicked();
        void processData();
    
        void data_send();
    
    private:
    
        Ui::udpSimulationClientClass ui;
        QUdpSocket* m_sender;
        QUdpSocket* m_receiver;
        QTimer* timer;
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • .cpp文件
    #include "udpSimulationClient.h"
    
    
    
    udpSimulationClient::udpSimulationClient(QWidget *parent)
        : QMainWindow(parent)
    {
        ui.setupUi(this);
        m_sender = new QUdpSocket(this);
    
        m_receiver = new QUdpSocket(this);
        m_receiver->bind(7777, QUdpSocket::ShareAddress);
    
        //数据报到来时readyRead信号触发
        connect(m_receiver, &QUdpSocket::readyRead, this, &udpSimulationClient::processData);
    
    }
    
    udpSimulationClient::~udpSimulationClient()
    {
       
    }
    
    
    void udpSimulationClient::on_pushButton_clicked()
    {
        //QByteArray dataGram = ui.lineEdit->text().toUtf8();
        QString Msg = ui.lineEdit->text() + QString(";") + ui.lineEdit_2->text() + QString(";") 
            + ui.lineEdit_3->text() + QString(";") + ui.lineEdit_5->text() + QString(";") 
            + ui.lineEdit_4->text() + QString(";") + ui.lineEdit_6->text() + QString(";");
        //qint64 QUdpSocket::writeDatagram(const char *data, qint64 size, const QHostAddress &address, quint16 port)
        m_sender->writeDatagram(Msg.toLatin1(), Msg.toUtf8().size(), QHostAddress::Broadcast, 6666);
    
    
    }
    
    void udpSimulationClient::processData()
    {
        QString strData;
        while (m_receiver->hasPendingDatagrams())
        {
            
            QByteArray dataGram;
            dataGram.resize(m_receiver->pendingDatagramSize());
            m_receiver->readDatagram(dataGram.data(), dataGram.size());
            //ui.lineEdit_12->setText(dataGram);
            
            QString status_judge = dataGram;
            if (status_judge.contains(QString("heart"), Qt::CaseSensitive))
            {
                //隔1s传输一次心跳状态数据
                timer = new QTimer(this);
                connect(timer, &QTimer::timeout, this, &udpSimulationClient::data_send);
                timer->start(1000);
            }
            else if (status_judge.contains(QString("selfcheck"), Qt::CaseSensitive))
            {
                QString Msg = QString("selfcheck") + QString(";") + ui.lineEdit_10->text() + QString(";") + ui.lineEdit_11->text() + QString(";")
                    + ui.lineEdit_9->text() + QString(";");
                m_sender->writeDatagram(Msg.toLatin1(), Msg.toUtf8().size(), QHostAddress::Broadcast, 8888);
            }
            else if (status_judge.contains(QString("FPGA"), Qt::CaseSensitive))
            {
                QString Msg = QString("FPGA") + QString(";") + ui.lineEdit_7->text() + QString(";") + ui.lineEdit_8->text() + QString(";");
                m_sender->writeDatagram(Msg.toLatin1(), Msg.toUtf8().size(), QHostAddress::Broadcast, 8888);
            }
    
    
    
         
    
        }
    
    
    }
    
    
    void udpSimulationClient::data_send()
    {
        QString Msg = QString("heart") + QString(";") + ui.lineEdit_14->text() + QString(";") + ui.lineEdit_12->text() + QString(";")
            + ui.lineEdit_13->text() + QString(";");
        m_sender->writeDatagram(Msg.toLatin1(), Msg.toUtf8().size(), QHostAddress::Broadcast, 8888);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84

    效果

    下面展示一些 内联代码片

    /******************************************************************************
     * @文件名    udpSimulationServer.h
     * @功能       简易的UDP通信功能Demo,第一种实现方式,传统UDP通信方式。
     *
     * @开发者    
     * @邮箱       
     * @时间       2022/06/24
     * @备注
     *****************************************************************************/
    #pragma once
    
    #include <QtWidgets/QMainWindow>
    #include "ui_udpSimulationServer.h"
    #include <qudpsocket.h>
    
    class udpSimulationServer : public QMainWindow
    {
        Q_OBJECT
    
    public:
        udpSimulationServer(QWidget *parent = nullptr);
        ~udpSimulationServer();
    
    private slots:
        void processData();
        void on_pushButton_clicked();
        void processData2();
    private:
        Ui::udpSimulationServerClass ui;
        QUdpSocket* m_receiver;
       
        QUdpSocket* m_sender;
    
        QUdpSocket* m_receiver2;
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • .cpp文件
    #include "udpSimulationServer.h"
    
    udpSimulationServer::udpSimulationServer(QWidget *parent)
        : QMainWindow(parent)
    {
        ui.setupUi(this);
        m_receiver = new QUdpSocket(this);
        m_sender = new QUdpSocket(this);
        m_receiver2 = new QUdpSocket(this);
    
        //绑定发送端,Shareaddress允许多接收端绑定6666端口
        m_receiver->bind(6666, QUdpSocket::ShareAddress);
        //接收端接收到数据时,就会发送readRead消息
        connect(m_receiver, &QUdpSocket::readyRead, this, &udpSimulationServer :: processData);
    
        m_receiver2->bind(8888, QUdpSocket::ShareAddress);
        connect(m_receiver2, &QUdpSocket::readyRead, this, &udpSimulationServer::processData2);
    
    
    }
    
    udpSimulationServer::~udpSimulationServer()
    {}
    
    void udpSimulationServer::processData()
    {
        QString strData;
    
        while (m_receiver->hasPendingDatagrams())
        {
            QByteArray dataGram;
            dataGram.resize(m_receiver->pendingDatagramSize());
            m_receiver->readDatagram(dataGram.data(), dataGram.size());
            //ui.lineEdit_5->setText(dataGram);//将接收到的数据显示到标签上
            QString Msg = dataGram;
            QStringList Msglist = Msg.split(";");
            ui.lineEdit_5->setText(Msglist[0]);
            ui.lineEdit_6->setText(Msglist[1]); 
            ui.lineEdit_14->setText(Msglist[2]);
            ui.lineEdit->setText(Msglist[3]);
            ui.lineEdit_3->setText(Msglist[4]);
            ui.lineEdit_15->setText(Msglist[5]);
        }
    }
    
    void udpSimulationServer::processData2()
    {
        QByteArray dataGram;
        dataGram.resize(m_receiver2->pendingDatagramSize());
        m_receiver2->readDatagram(dataGram.data(), dataGram.size());
    
        QString Msg = dataGram;
        QStringList Msglist = Msg.split(";");
    
        if (Msg.contains(QString("heart")))
        {
            ui.lineEdit_11->setText(Msglist[1]);
            ui.lineEdit_12->setText(Msglist[2]);
            ui.lineEdit_10->setText(Msglist[3]);
        }
        else if (Msg.contains(QString("selfcheck")))
        {
            ui.lineEdit_8->setText(Msglist[1]);
            ui.lineEdit_7->setText(Msglist[2]);
            ui.lineEdit_9->setText(Msglist[3]);
        }
        else if (Msg.contains(QString("FPGA")))
        {
            ui.lineEdit_4->setText(Msglist[1]);
            ui.lineEdit_2->setText(Msglist[2]);
        }
    
    
    }
    
    void udpSimulationServer::on_pushButton_clicked()
    {
        QString msg = "status:";
       // QByteArray dataGram = msg.toLatin1() +  ui.lineEdit_13->text().toUtf8();
        QByteArray dataGram = msg.toLatin1() + ui.comboBox->currentText().toUtf8();
        m_sender->writeDatagram(dataGram.data(), dataGram.size(), QHostAddress::Broadcast, 7777);
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84

    效果
    在这里插入图片描述

    • 接收指令:”status:heart”,则隔1s传输一次心跳状态数据;
    • 接收指令:”status:selfcheck”,则返回设备自检结果;
    • 接收指令:”status:FPGA”,则返回FPGA”模块结果;
    • 点击发送按钮,则将射电模块数据发送给控制端
  • 相关阅读:
    如何正确的在C++中实现单例SingleTone模式
    类和对象(封装)
    计算机毕业设计Java大型商场应急预案管理系统(源码+系统+mysql数据库+lw文档)
    【数据结构】单链表OJ题(二)
    Oracle数据如何迁移导入到MySQL
    美团外卖优惠券小程序 美团优惠券微信小程序 自带流量主模式 带教程
    解决Microsoft Edge无法正常运行的有效方案分享!
    Git 学习笔记 | 使用码云
    c#如何判断一个类型是否为数值类型,请给出通用方法
    0xC004F069错误的解决方案
  • 原文地址:https://blog.csdn.net/gszhlw/article/details/125443986