Qt实战案例(30)——利用QUdpSocket类实现UDP网络广播通信

目录

一、项目介绍

利用QUdpSocket类实现UDP网络广播通信,其原理如下图所示。
Qt实战案例(30)——利用QUdpSocket类实现UDP网络广播通信
UDP的工作原理是:UDP客户端向UDP服务器发送一定长度的请求报文,报文大小的限制与各系统的协议实现有关,但不得超过其下层IP规定的64KB;UDP服务器同样以报文形式做出响应。如果服务器未收到此请求,客户端不会进行重发,因此报文的传输是不可靠的。这便是UDP的主要缺点。

二、项目基本配置

新建一个Qt案例,项目名称为“Server”,基类选择“QDialog”,类名为“Server”,取消创建UI界面复选框的选中状态,完成项目创建。【该项目为UDP服务器,内容详见4.1和4.2】
再新建一个Qt案例,项目名称为“Client”,基类选择“QDialog”,类名为“Client”,取消创建UI界面复选框的选中状态,完成项目创建。【该项目为UDP客户端,内容详见4.3和4.4】

三、UI界面设计

无UI界面

四、主程序实现

4.0 pro文件

首先需要在两个pro文件中添加如下代码:

QT+=network

4.1 server.h头文件

头文件中声明私有变量和一些槽函数:

public slots:
    void StartBtnClicked();//按钮点击槽函数
    void timeout();

private:
    QLabel *TimerLabel;
    QLineEdit *TextLineEdit;
    QPushButton *StartBtn;
    QVBoxLayout *mainLayout;

    int port;
    bool isStarted;
    QUdpSocket *udpSocket;
    QTimer *timer;

4.2 server.cpp源文件

创建界面,设置相应布局:

    /*创建界面*/
    setWindowTitle(tr("UDP Server")) ;//设置窗体的标题
    //初始化各个控件
    TimerLabel = new QLabel(tr("计时器:"),this);
    TextLineEdit= new QLineEdit(this);
    StartBtn = new QPushButton(tr("开始"),this);
    //设置布局
    mainLayout= new QVBoxLayout (this);
    mainLayout->addWidget(TimerLabel);
    mainLayout->addWidget(TextLineEdit);
    mainLayout->addWidget(StartBtn);

设置连接的槽函数:

    connect(StartBtn,SIGNAL(clicked()),this, SLOT(StartBtnClicked()));//点击开始按钮对应槽函数
    port= 5555;    //设置UDP的端口号参数,服务器定时向此端口发送广播信息
    isStarted = false;
    udpSocket = new QUdpSocket(this);//新建一个QUdpSocket
    timer = new QTimer(this);
    //定时发送广播信息
    connect(timer,SIGNAL(timeout()),this,SLOT(timeout()));

按钮点击槽函数:

void Server::StartBtnClicked()
{
    if(!isStarted)
    {
        StartBtn->setText(tr("停止"));
        timer->start(1000);//时间间隔为1000ms
        isStarted=true;
    }else{
        StartBtn->setText (tr("开始"));
        isStarted = false;
        timer->stop();
    }
}

发送广播槽函数:

//向端口发送广播信息
void Server::timeout()
{
    QString msg= TextLineEdit->text();//获取待发送的文本内容
    int length=0;
    if (msg=="")
    {
        return;
    }
    //发送广播msg
    if((length=udpSocket->writeDatagram(msg.toLatin1(),
    msg.length(),QHostAddress::Broadcast,port))!=msg.length())
    {
        return;
    }
}

4.3 client.h头文件

头文件中声明私有变量和一些槽函数:

public slots:
    void dataReceived();
private:
    QTextEdit *ReceiveTextEdit;
    QPushButton *CloseBtn;
    QVBoxLayout *mainLayout;

    int port;
    QUdpSocket *udpSocket;

4.4 client.cpp源文件

首先创建界面,设置相应布局:

    setWindowTitle(tr("UDP Client")); //设置窗体的标题
    //初始化各个控件
    ReceiveTextEdit= new QTextEdit(this) ;
    CloseBtn = new QPushButton(tr ("Close"),this) ;
    //设置布局
    mainLayout=new QVBoxLayout(this) ;
    mainLayout->addWidget(ReceiveTextEdit);
    mainLayout->addWidget(CloseBtn);

设置相应的连接,接受广播信息:

    connect (CloseBtn, SIGNAL (clicked()), this, SLOT (close()));//关闭
    port =5555;    //设置UDP的端口号参数,指定在此端口上监听数据
    udpSocket = new QUdpSocket (this); //创建一个QudpSocket
    connect (udpSocket, SIGNAL(readyRead()), this, SLOT (dataReceived())) ;//当有数据到达IO设备时,触发dataReceived()函数
    bool result=udpSocket->bind(port);//绑定到指定的端口上
    if(!result)
    {
        QMessageBox::information(this, tr("error"), tr ("udp socket create error!"));
        return;
    }

接收广播槽函数:

//一旦有数据可读时,即通过readDatagram方法将数据读取并显示
void Client::dataReceived()
{
    while(udpSocket->hasPendingDatagrams())    //判断udpSocket是否有数据正在等待读取
    {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());//调整大小
        udpSocket->readDatagram(datagram.data(), datagram.size());//读取第一个datagram的长度
        QString msg=datagram.data();
        ReceiveTextEdit-> insertPlainText(msg);    //显示数据内容
    }
}

五、效果演示

同时运行这两个Qt程序,完整效果如下:
Qt实战案例(30)——利用QUdpSocket类实现UDP网络广播通信

如果没有看懂的话,完整代码可以参考:https://download.csdn.net/download/didi_ya/77497306


ok,以上便是本文的全部内容了,如果对你有所帮助,记得点个赞哟~

上一篇:linux定时删除文件-crontab


下一篇:leetcode刷题-剑指offer-30题