【QT】数据广播(QUdpSocket类)

一、基础知识

QUdpSocket 类:这个类专门用来做网络之间的数据广播 ,所谓的数据广播:只有一台设备负责发送数据,并且该设备不接受数据 ,剩余所有设备负责接受数据,并且不能发送数据

QUdpSocket的操作步骤: ① 创建QUdpSocket对象  ② 绑定广播地址和端口号

注意,绑定形式不同,广播的形式也不同的 ,广播分为2种形式: 1:广播形式 2:组播形式

这两种形式的唯一区别在于:广播默认广播地址为 255.255.255.255,组播的话,需要自己填写一个广播地址,并且使用的组播的情况下,数据的接收方需要加入该组播地址(广播的话,不需要加入地址) 所以,绑定ip地址和端口号的函数,也会有2个不同的形式

广播:bool QAbstractSocket::bind(quint16 port = 0, BindMode mode = DefaultForPlatform) port:端口号,不需要填广播地址,默认为 255.255.255.255

mode:套接字形式,一般选择QAbstractSocket::ReuseAddressHint

组播:bind(const QHostAddress &address, quint16 port = 0, BindMode mode = DefaultForPlatform)

address:组播地址,范围为 224.0.0.1~255.255.255.254 ,这里应该写 QHostAddress::AnyIPv4 port:同上

mode:同上

注意,bind函数是广播的接受方调用,根据情况还需要调用加入广播组 ,广播的发送方,在发送数据的时候,明确一下广播地址和port即可

bool joinMulticastGroup(const QHostAddress &groupAddress)  参数填写广播组地址即可

关于广播的数据发送: 注意QTcpSocket 和 QUdpSocket,他们的套接字类型是不一样的,所以数据发送的函数就不一样的

一个叫数据报类型 writeDataGram 和 readDataGram

例如:qint64 writeDatagram(const char *data, qint64 size, const QHostAddress &address, quint16 port)

data:想要发送的数据

size:发送的数据的尺寸

address:将数据发送到的广播地址

port:将数据发送到的地方的端口号

另一个叫字节流类型 write和read

二,代码实现

1.创建一个QT文件,在.Pro文件中添加 QT     += network, 这一步不可缺少,没有这一步,QT就无法连接网络编程相关的头文件

 2.点击widget.h头文件,添加两个QUdpSocket 类的指针和两个槽函数,关键的头文件<QUdpSocket>不能忘记,如果第一步没做,这个头文件也就无法使用

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QUdpSocket>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_pushButton_clicked();  // 按钮的槽函数,点击按钮后发送信号

private:
    Ui::Widget *ui;
    QUdpSocket* reciver;     //QUdpSocket对象,接收  
    QUdpSocket* sender;     //QUdpSocket对象, 发送

public slots:
    void onReadyRead();    //自定义的槽函数,当接收方接收到信号时触发
};

#endif // WIDGET_H

 3.点击widget.cpp文件,将功能完善,相应的函数原型以注释

#include "widget.h"
#include "ui_widget.h"

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

    sender = new QUdpSocket(this);// 在未来发送数据的时候,明确ip和port即可
    reciver = new QUdpSocket(this);// 需要绑定一下接受数据的ip和port,根据情况不同,还需要加入广播组

    // 广播代码
    //reciver->bind(12345,QUdpSocket::ReuseAddressHint);   // 端口号 套接字形式


    // 组播代码
    reciver->bind(QHostAddress::AnyIPv4,12345,QUdpSocket::ReuseAddressHint);  //组播地址 端口号 套接字形式
    reciver->joinMulticastGroup(QHostAddress("224.0.0.1"));                  //广播接收方接收来自地址发出的信号

    QObject::connect(reciver,SIGNAL(readyRead()),this,SLOT(onReadyRead()));  //获取信号:void QIODevice::readyRead()后,执行自定义的槽函数

}

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

void Widget::on_pushButton_clicked()                         //按钮槽函数的实现
{
    QString str = ui->lineEdit->text();                    //获取行编辑器中的文字
    // 广播
    //sender->writeDatagram(str.toLocal8Bit(),QHostAddress::Broadcast,12345); //qint64 QUdpSocket::writeDatagram(const char *data, qint64 size, const QHostAddress &address, quint16 port)

    // 组播
    sender->writeDatagram(str.toLocal8Bit(),QHostAddress("224.0.0.1"),12345);   //发送信号 字符串转化成本地八位表示,QByteArray QString::toLocal8Bit() const



    reciver->close();                      // 广播方,也就是数据发送方,不通过reciver接受数据,直接通过本地获取数据
    ui->textEdit->append(str);
    ui->lineEdit->clear();
}

void Widget::onReadyRead()                     //自定义槽函数的实现
{
    int size = reciver->pendingDatagramSize(); //获取接受到的数据的大小,QTcpSocket是bytesAvalible , qint64 QUdpSocket::pendingDatagramSize() const 
    char buf[size+1] = {0};
    reciver->readDatagram(buf,size); //接收数据,限定大小 qint64 QUdpSocket::readDatagram(char *data, qint64 maxSize, QHostAddress *address = Q_NULLPTR, quint16 *port = Q_NULLPTR)

    QString str = QString::fromLocal8Bit(buf); //将字符数组转化QString类型 QString QString::fromLocal8Bit(const char *str, int size = -1)
    ui->textEdit->append(str);
}

4.widget.ui文件的设置

 三、效果验证

1.编译成功后,点击三次运行,构建三个窗口类对象,在窗口一中输入“多学多练”,窗口二和窗口三同时展现出“多学多练”

 2.实现广播功能,效果实现!

四、扩展功能

如果想要界面美观化,可添加资源文件,修改UI文件,如果想扩展功能,可在cpp文件中添加相应功能代码

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值