QT day07(1)

1 基于UDP的网络广播
2 基于QT的聊天室程序
1 基于UDP的网络广播
1.1 问题
实现基于UDP的网络广播。

1.2 方案
QUdpSocket封装了UDP套接字,通过该类可以非常方便的建立UDP通信的连接,通过bind()函数实现绑定一个地址和端口,然后调用writeDatagram()函数实现发送消息,以及用readDatagram()实现从UDP套接字读取消息。本案例分别实现UDP发送端和接收端,在UDP发送端,通过writeDatagram()函数往广播地址发送文本控件中的信息,在接收端接收发送端的信息,并在界面上显示。

1.3 步骤
实现此案例需要按照如下步骤进行。

步骤一:创建UdpSender工程

终端输入:qtcreator或点击桌面qt图标。启动Qt创造器。

选择菜单"file/file or project",在"新建"对话框中依次选择"application"和"QT widgets Application",并点击"choose…"

在"项目介绍和位置"中指定项目的名称为:UdpSender,并选择存储路径,Qt会在该路径下创建工程目录,点击"next"

在"kits"中选择"Desktop Qt 5.4.1 Gcc 64bit",前面打勾,点击"next"

在"Class information"中选择"QDialog"作为"Base class",并将"class name"设置为"UdpSender",勾选"Generate form",点击"next" ,点击"finsh"。

步骤二:使用设计师设计界面

双击UdpSender.ui,打开Qt设计师,开始设计界面
QT day07(1)
步骤三:编写源程序头文件UdpSender.h

双击UdpSender.h文件,编写头文件,代码如下:

#ifndef UDPSENDER_H
#define UDPSENDER_H
#include
#include
#include
namespace Ui {
class UdpSender;
}
class UdpSender : public QDialog
{
Q_OBJECT
public:
explicit UdpSender(QWidget *parent = 0);
~UdpSender();
private slots:
void on_startButton_clicked();
void sendMessage(void);
private:
Ui::UdpSender *ui;
bool isStarted;//判断是否已经开始广播
QUdpSocket *udpSocket;//UDP套接字
QTimer *timer;//定时器广播消息
};
#endif // UDPSENDER_H
步骤四:编写源程序文件UdpSender.cpp。

双击UdpSender.cpp文件,编写源文件,代码如下:

#include “UdpSender.h”
#include “ui_UdpSender.h”
UdpSender::UdpSender(QWidget *parent) :
QDialog(parent),
ui(new Ui::UdpSender)
{
ui->setupUi(this);
isStarted = false;
udpSocket = new QUdpSocket(this);
timer = new QTimer(this);
connect(timer,SIGNAL(timeout()),this,SLOT(sendMessage()));
}
UdpSender::~UdpSender()
{
delete ui;
}
void UdpSender::on_startButton_clicked()
{
if(!isStarted)
{
ui->startButton->setText(“停止广播”);
timer->start(1000);//每个1s广播一次
isStarted =true;
ui->portEdit->setEnabled(false);
ui->messageEdit->setEnabled(false);
}
else
{
ui->startButton->setText(tr(“开始广播”));
isStarted = false;
ui->portEdit->setEnabled(true);
ui->messageEdit->setEnabled(true);
timer->stop();
}
}
void UdpSender::sendMessage()
{
quint16 port = ui->portEdit->text().toInt();
QString msg = ui->messageEdit->text();
if(msg==""){
return;
}
qDebug() << msg;
udpSocket->writeDatagram(msg.toLocal8Bit(),QHostAddress::Broadcast,port);
}
步骤五:编译运行

代码编辑完后,即可对工程进行编译,点击绿色按钮,即可编译运行,如果代码有错,会给出错误信息,运行结果如下图-2所示:
QT day07(1)
步骤六:创建Receiver工程

终端输入:qtcreator或点击桌面qt图标。启动Qt创造器。

选择菜单"file/file or project",在"新建"对话框中依次选择"application"和"QT widgets Application",并点击"choose…"

在"项目介绍和位置"中指定项目的名称为:Receiver,并选择存储路径,Qt会在该路径下创建工程目录,点击"next"

在"kits"中选择"Desktop Qt 5.4.1 Gcc 64bit",前面打勾,点击"next"

在"Class information"中选择"QDialog"作为"Base class",并将"class name"设置为"updReceiver",勾选"Generate form",点击"next" ,点击"finsh"。

步骤七:使用设计师设计界面

双击udpReceiver.ui,打开Qt设计师,设计界面如图-3所示:
QT day07(1)
步骤八:编写源程序头文件udpReceiver.h

双击udpReceiver.h文件,编写头文件,代码如下:

#ifndef UDPRECEIVER_H
#define UDPRECEIVER_H
#include
#include
#include
namespace Ui {
class udpReceiver;
}
class udpReceiver : public QDialog
{
Q_OBJECT
public:
explicit udpReceiver(QWidget *parent = 0);
~udpReceiver();
private slots:
void on_startButton_clicked();
void messageReceived(void);
private:
Ui::udpReceiver *ui;
QUdpSocket *udpSocket;//接收广播消息套接字
quint16 port;
bool isStarted;
};
#endif // UDPRECEIVER_H
步骤九:编写源程序文件udpReceiver.cpp。

双击udpReceiver.cpp文件,编写源文件,代码如下:

#include “udpReceiver.h”
#include “ui_udpReceiver.h”
udpReceiver::udpReceiver(QWidget *parent) :
QDialog(parent),
ui(new Ui::udpReceiver)
{
ui->setupUi(this);
udpSocket = new QUdpSocket(this);
isStarted = false;
}
udpReceiver::~udpReceiver()
{
delete ui;
}
void udpReceiver::messageReceived(void){
if(udpSocket->hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(udpSocket->pendingDatagramSize());
udpSocket->readDatagram(datagram.data(),datagram.size());
QString msg=datagram.data();
ui->listWidget->addItem(msg);
//ReceiveTextEdit->insertPlainText(msg);
}
}
void udpReceiver::on_startButton_clicked()
{
if(!isStarted){
isStarted = true;
port = ui->portEdit->text().toInt();
bool result=udpSocket->bind(port);
if(!result){
QMessageBox::information(this,tr(“error”),tr(“udp socket create error!”));
return;
}
ui->portEdit->setEnabled(false);
ui->startButton->setText(“停止接收”);
connect(udpSocket,SIGNAL(readyRead()),this,SLOT(messageReceived()));
}
else{
udpSocket->close();
isStarted = false;
ui->portEdit->setEnabled(true);
ui->startButton->setText(“开始接收”);
}
}
步骤十:编译运行

代码编辑完后,即可对工程进行编译,点击绿色按钮,即可编译运行,如果代码有错,会给出错误信息,运行结果如下图-4所示:
QT day07(1)
1.4 完整代码
本案UdpSender.h文件完整代码如下所示:

#ifndef UDPSENDER_H
#define UDPSENDER_H
#include
#include
#include
namespace Ui {
class UdpSender;
}
class UdpSender : public QDialog
{
Q_OBJECT
public:
explicit UdpSender(QWidget *parent = 0);
~UdpSender();
private slots:
void on_startButton_clicked();
void sendMessage(void);
private:
Ui::UdpSender *ui;
bool isStarted;//判断是否已经开始广播
QUdpSocket *udpSocket;//UDP套接字
QTimer *timer;//定时器广播消息
};
#endif // UDPSENDER_H
本案UdpSender.cpp文件完整代码如下所示:

#include “UdpSender.h”
#include “ui_UdpSender.h”
UdpSender::UdpSender(QWidget *parent) :
QDialog(parent),
ui(new Ui::UdpSender)
{
ui->setupUi(this);
isStarted = false;
udpSocket = new QUdpSocket(this);
timer = new QTimer(this);
connect(timer,SIGNAL(timeout()),this,SLOT(sendMessage()));
}
UdpSender::~UdpSender()
{
delete ui;
}
void UdpSender::on_startButton_clicked()
{
if(!isStarted)
{
ui->startButton->setText(“停止广播”);
timer->start(1000);//每个1s广播一次
isStarted =true;
ui->portEdit->setEnabled(false);
ui->messageEdit->setEnabled(false);
}
else
{
ui->startButton->setText(tr(“开始广播”));
isStarted = false;
ui->portEdit->setEnabled(true);
ui->messageEdit->setEnabled(true);
timer->stop();
}
}
void UdpSender::sendMessage()
{
quint16 port = ui->portEdit->text().toInt();
QString msg = ui->messageEdit->text();
if(msg==""){
return;
}
qDebug() << msg;
udpSocket->writeDatagram(msg.toLocal8Bit(),QHostAddress::Broadcast,port);
}
本案udpReceiver.h文件完整代码如下所示:

#ifndef UDPRECEIVER_H
#define UDPRECEIVER_H
#include
#include
#include
namespace Ui {
class udpReceiver;
}
class udpReceiver : public QDialog
{
Q_OBJECT
public:
explicit udpReceiver(QWidget *parent = 0);
~udpReceiver();
private slots:
void on_startButton_clicked();
void messageReceived(void);
private:
Ui::udpReceiver *ui;
QUdpSocket *udpSocket;//接收广播消息套接字
quint16 port;
bool isStarted;
};
#endif // UDPRECEIVER_H
本案udpReceiver.cpp文件完整代码如下所示:

#include “udpReceiver.h”
#include “ui_udpReceiver.h”
udpReceiver::udpReceiver(QWidget *parent) :
QDialog(parent),
ui(new Ui::udpReceiver)
{
ui->setupUi(this);
udpSocket = new QUdpSocket(this);
isStarted = false;
}
udpReceiver::~udpReceiver()
{
delete ui;
}
void udpReceiver::messageReceived(void){
if(udpSocket->hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(udpSocket->pendingDatagramSize());
udpSocket->readDatagram(datagram.data(),datagram.size());
QString msg=datagram.data();
ui->listWidget->addItem(msg);
//ReceiveTextEdit->insertPlainText(msg);
}
}
void udpReceiver::on_startButton_clicked()
{
if(!isStarted){
isStarted = true;
port = ui->portEdit->text().toInt();
bool result=udpSocket->bind(port);
if(!result){
QMessageBox::information(this,tr(“error”),tr(“udp socket create error!”));
return;
}
ui->portEdit->setEnabled(false);
ui->startButton->setText(“停止接收”);
connect(udpSocket,SIGNAL(readyRead()),this,SLOT(messageReceived()));
}
else{
udpSocket->close();
isStarted = false;
ui->portEdit->setEnabled(true);
ui->startButton->setText(“开始接收”);
}
}