QT 基于UDP的网络广播程序

先来看一下效果图
QT 基于UDP的网络广播程序_第1张图片
流程就是分别实现UDP下的客户端和服务器端。
开始之前,先说一下UDP的特点,
QT 基于UDP的网络广播程序_第2张图片
QT 基于UDP的网络广播程序_第3张图片
QT 基于UDP的网络广播程序_第4张图片
QT 基于UDP的网络广播程序_第5张图片
选自《Qt5 开发及实例》陆文周著

接下来开始我们的实例

首先创建服务器端的项目,我这里使用的基类为QDialog,并在ui界面作如下部署
QT 基于UDP的网络广播程序_第6张图片
然后在.pro里添加

QT += network

在.h文件中添加头文件

#include 
#include
#include

类里添加

private slots:
    void timeout();
    //按钮的响应函数
    void on_pushButton_clicked();

私有属性里添加

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

然后在对应的cpp文件中的构造函数中添加

	port = 5555;
    isStarted = false;
    udpSocket = new QUdpSocket(this);
    timer = new QTimer(this);
    //定时发送广播消息
    connect(timer,SIGNAL(timeout()),this,SLOT(timeout()));

QT 基于UDP的网络广播程序_第7张图片

现在实现开始按钮的响应函数

	if(!isStarted)
    {
        ui->pushButton->setText(tr("停止"));
        timer->start(1000);
        isStarted = true;
    }
    else
    {
        ui->pushButton->setText(tr("开始"));
        isStarted = false;
        timer->stop();
        udpSocket->abort();//用于解绑端口
    }

就像这样
QT 基于UDP的网络广播程序_第8张图片
继续实现timeout()函数

	udpSocket->bind(port);//绑定到port端口
    //udpSocket->abort();//用于解绑端口
    QString msg = ui->lineEdit->text();
    //int length = 0;
    if(msg == "")
    {
        return;
    }
    QByteArray datagram;
    datagram.append(msg);//数据报填充字节数据
    QHostAddress RemoteIP("192.168.56.1");//添加远端IP
    quint16 RemotePort(port);//添加远端端口号

    udpSocket->writeDatagram(datagram,RemoteIP,RemotePort);

QT 基于UDP的网络广播程序_第9张图片
这样服务器端就完成了,接下来实现客户端

同理创建客户端项目,在ui界面如下部署
QT 基于UDP的网络广播程序_第10张图片
close按钮用来关闭程序
同样需要在.pro里添加

QT += network

在.h文件中添加头文件

#include

在类里添加

private slots:
    void on_pushButton_clicked();
    void dataReceived();

在私有属性里定义如下变量

	quint16 port;
    QUdpSocket *udpSocket;

这里是我的.h文件(部分)
QT 基于UDP的网络广播程序_第11张图片
然后在对应的cpp文件的构造函数添加

	setWindowTitle(tr("UDP Client"));
    port = 5555;
    udpSocket = new QUdpSocket(this);
    //这里需要注意一下,
    /*
     连接QIODevice的readyRead()信号。
     QUdpSocket也是一个I/O设备,从QIODevice继承而来,当有数据到达
     I/O设备时,发出readyRead()信号
     */
    connect(udpSocket,SIGNAL(readyRead()),this,SLOT(dataReceived()));

    //绑到指定的端口号
    bool result = udpSocket->bind(port);
    //qDebug()<
    if(!result)
    {
        QMessageBox::information(this,tr("error"),tr("udp socket create error!"));
        return;
    }

QT 基于UDP的网络广播程序_第12张图片
按钮的响应函数里添加

//关闭程序
close();

最后实现dataReceived()函数

/*判断UdpSocket中是否有数据报可读,
    hasPendingDatagrams()方法在至少有一个数据报可读时返回true
    */
    while(udpSocket->hasPendingDatagrams())
    {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());//设置字节数组大小
        QHostAddress remoteIP("192.168.56.1");//接收远端IP
        quint16 remotePort(port);//接收远端端口号
        udpSocket->readDatagram(datagram.data(),datagram.size(),&remoteIP,&remotePort);//读取数据
        QString str=datagram.data();//将读取的数据转化为字符串
        ui->textEdit->insertPlainText(str+"\n");
    }

最后附上QT创建UDP的流程以及基本函数功能表

函数 功能
bool bind (quint16 port) 为UDP通信绑定一个端口
bool abort ( ) 释放为UDP绑定的端口
qint64 writeDatagram(QByteArray &datagram, QHostAddress &host, quint16 port) 数据报发送,形参分别为数据报,目的IP地址,目的端口号
bool hasPendingDatagram() 接收到数据报时,返回值为true
qint64 pendingDatagramSize() 返回待读取数据报的大小
qint64 readDatagram(char *data, qint64 maxSize) 读取数据报,返回读取数据报的字节数,maxSize为设置的读取字节数,还可以加上源IP和源端口号

UDP发送

QUdpSocket  *udpSocket;
//端口绑定与解绑操作
quint16 port=8080;
udpSocket->bind(port);//绑定到port端口
udpSocket->abort();//用于解绑端口
//发送数据报操作
QByteArray datagram;
datagram.append(0xAA);//数据报填充字节数据

QHostAddress RemoteIP(192.168.0.1);//添加远端IP
quint16 RemotePort(port);//添加远端端口号

udpSocket->writeDatagram(datagram,RemoteIP,RemotePort);

UDP接收

//信号槽设置
connect(udpSocket,SIGNAL(readyRead()),this,SLOT(UDPReceive()));//添加信号与槽的连接,当主机端口接收到数据时readyRead()有效,进而触发跳转到UDPReceive()函数;其中readyRead()为Qt中QIODEVICE类中函数,UDPReceive()是需要自己编写的函数。
//字节读取
while(udpSocket->hasPendingDatagrams()){//判断有数据报接收到
	 QByteArray datagram;
     datagram.resize(udpSocket->pendingDatagramSize());//设置字节数组大小
     QHostAddress remoteIP;//接收远端IP
     quint16 remotePort;//接收远端端口号
     udpSocket->readDatagram(datagram.data(),datagram.size(),&remoteIP,&remotePort);//读取数据
    QString str=datagram.data();//将读取的数据转化为字符串
}

参考文献
《Qt5.9 c++开发指南》王维波著,P400

你可能感兴趣的:(Qt,udp,qt,网络)