您的位置:首页 > 编程语言 > Qt开发

QT:UDP网络编程实现

2017-04-04 00:53 435 查看
QT UDP编程

QUdpSocket  UDP套接字   -  More.... 里面的Example伪代码

读写操作在成员函数内。
void QIODevice::readyRead ( );   // 适用于所有I/O通信

/** assistant 伪代码演示 **/

void Server::initSocket ( ) {
// 创建UDP套接字
udpSocket = new QUdpSocket (this);
// 绑定
udpSocket->bind (QHostAddress::LocalHost, 7755);
// 当套接字有数据时会发送 readyRead ( )
connect (udpSocket, SIGNAL (readyRead( )), this, SLOT (readPendingDatagrams( )));
}
void Server::readPendingDatagrams ( ) {
// 判断当前套接字是否有数据包到来
while (udpSocket->hasPendingDatagrams ( )) {
// 数据缓冲区,类似 char [ ]
QByteArray datagram;
// 获取当前数据包的大小,从到来的套接字数据包
datagram.resize (udpSocket->pendingDatagramSize ( ));
QHostAddress sender; // 保存客户端的IP地址
quint16 senderPort; // 保存客户端的端口号
// 读取数据,.data ( )完成的是数据类型转换为 char *
udpSocket->readDatagram (datagram.data ( ), datagram.size ( ), &sender, &senderPort);
// 解析和处理...
processTheDatagram (datagram);
}
}
《案例》UDP网络广播

1 )发送广播地址

 指定广播地址:255.255.255.255  ' QHostAddress::Broadcast '

 // enum QHostAddress::SpecialAddress

 指定广播端口:8888

 通过定时器,每隔1s广播1条消息

mkdir UdpBroadcast

工程名:UdpSender

类名:UdpSenderDialog

UdpSender.pro   --->   QT += network

2 )接收广播消息

 绑定接收的端口号

 接收广播消息,并显示

工程名:UdpReceiver

类名:UdpReceiverDialog

UdpReceiver.pro  --->  QT += network

/* 发送广播地址 - 代码演示 */
// UdpSenderDialog.h
#ifndef UDPSENDERDIALOG_H
#define UDPSENDERDIALOG_H
#include <QDialog>
#include <QUdpSocket>
#include <QTimer> // 定时器
namespace Ui {
class UdpSenderDialog;
}
class UdpSenderDialog : public QDialog {
Q_OBJECT
public:
explicit UdpSenderDialog(QWidget *parent = 0);
~UdpSenderDialog();
private slots:
void on_startButton_clicked();
// 定时器到时后发送信息的槽函数
void sendMessage (void);
private:
Ui::UdpSenderDialog *ui;
bool isStarted; // 判断是否已经开始广播
QUdpSocket* udpSocket;
QTimer* timer; // 定时器,定时广播消息
};
#endif // UDPSENDERDIALOG_H
// UdpSenderDialog.cpp
#include "UdpSenderDialog.h"
#include "ui_UdpSenderDialog.h"
UdpSenderDialog::UdpSenderDialog (QWidget *parent) :
QDialog (parent),
ui(new Ui::UdpSenderDialog) {
ui->setupUi (this);
isStarted = false;
udpSocket = new QUdpSocket (this);
timer = new QTimer (this);
// 定时器到时以后发送timeout ()信号
connect (timer, SIGNAL (timeout ()), this, SLOT (sendMessage ()));
}
UdpSenderDialog::~UdpSenderDialog () {
delete ui;
}
void UdpSenderDialog::on_startButton_clicked () {
if (isStarted == false) {
// 开始广播
isStarted = true;
ui->startButton->setText ("停止广播");
// 禁用广播端口和消息输入的组件
ui->portEdit->setEnabled (false);
ui->messageEdit->setEnabled (false);
// 开启定时器,每隔1s广播一次
timer->start (100);
}
else {
// 停止广播
isStarted = false;
ui->startButton->setText ("开始广播");
ui->portEdit->setEnabled (true);
ui->messageEdit->setEnabled (true);
// 停止定时器
timer->stop ();
}
}
// 定时器到时后发送消息的槽函数
void UdpSenderDialog::sendMessage (void) {
// 获取端口号和广播的消息
quint16 port = ui->portEdit->text ().toShort ();
QString msg = ui->messageEdit->text ();
// 发送消息到广播地址 "255.255.255.255"
// toLocal8Bit ():QString ===> QByteArray
udpSocket->writeDatagram (msg.toLocal8Bit (), QHostAddress::Broadcast, port);
qDebug () << msg;
}
// main.cpp
#include "UdpSenderDialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
UdpSenderDialog w;
w.show();
return a.exec();
}


/* 接收广播消息 */// UdpReceiverDialog.h
#ifndef UDPRECEIVERDIALOG_H
#define UDPRECEIVERDIALOG_H
#include <QDialog>
#include <QUdpSocket>
#include <QMessageBox>
namespace Ui {
class UdpReceiverDialog;
}
class UdpReceiverDialog : public QDialog {
Q_OBJECT
public:
explicit UdpReceiverDialog(QWidget *parent = 0);
~UdpReceiverDialog();
private slots:
void on_startButton_clicked();
// 当套接字有数据到来,接收数据的槽函数
void messageReceived ();
void on_clearButton_clicked();
private:
Ui::UdpReceiverDialog *ui;
QUdpSocket* udpSocket;
quint16 port; // == unsigned short
bool isStarted; // 标记是否开始接收
};
#endif // UDPRECEIVERDIALOG_H
// UdpReceiverDialog.cpp
#include "UdpReceiverDialog.h"
#include "ui_UdpReceiverDialog.h"
UdpReceiverDialog::UdpReceiverDialog (QWidget *parent) :
QDialog (parent),
ui (new Ui::UdpReceiverDialog) {
ui->setupUi (this);
udpSocket = new QUdpSocket (this);
isStarted = false;
}
UdpReceiverDialog::~UdpReceiverDialog () {
delete ui;
}
void UdpReceiverDialog::on_startButton_clicked() {
if (isStarted == false) {
// 开始接收广播消息
isStarted = true;
// 获取和绑定接收消息的端口号
port = ui->portEdit->text ().toShort ();
bool res = udpSocket->bind (port);
if (res == false) {
// 弹出错误提示消息框
QMessageBox::information (this, "Error", "Udp bind error!");
return ;
}
// 禁用输入组件
ui->portEdit->setEnabled (false);
// 开始按钮内容改为停止接收
ui->startButton->setText ("停止接收");
// 监听套接字有数据发来时,将会发送信号 readyRead
connect (udpSocket, SIGNAL (readyRead ()), this, SLOT (messageReceived ()));
}
else {
// 停止接收
isStarted = false;
// 关闭套接字
udpSocket->close ();
// 使能输入组件
ui->portEdit->setEnabled (true);
// 停止按钮内容改为开始接收
ui->startButton->setText ("开始接收");
}
}
// 当套接字有数据到来,接收数据的槽函数
void UdpReceiverDialog::messageReceived () {
if (udpSocket->hasPendingDatagrams ()) {
QByteArray datagram;
datagram.resize (udpSocket->pendingDatagramSize ());
// data ():QByteArray ---> 转换为 char *
// 接收消息
udpSocket->readDatagram (datagram.data (), datagram.size ());
// 显示消息
ui->listWidget->addItem (datagram.data ());
}
}
void UdpReceiverDialog::on_clearButton_clicked() {
ui->listWidget->clear ();
}
// main.cpp
#include "UdpReceiverDialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
UdpReceiverDialog w;
w.show();
return a.exec();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  qt udp 网络编程