基於UDP(User Data Protocol,用戶數據報協議)的網絡廣播程序編程
一、 UDP是一種簡單輕量級、不可靠、面向數據報、無鏈接的傳輸層協議,能夠應用在可靠性不是十分重要的場合,如短消息、廣播信息等。安全
二、 特色服務器
網絡數據大多爲短消息網絡
擁有大量的客戶端socket
對數據安全性無特殊要求函數
網絡負擔很是重要,但對響應速度要求高佈局
三、 UDP客戶端與服務器間的交互時序ui
四、 服務器端編程this
udpserver.cpp文件orm
#ifndef UDPSERVER_H
#define UDPSERVER_H
#include <QDialog>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QVBoxLayout>
#include <QUdpSocket>
#include <QTimer>
class UdpServer : public QDialog
{
Q_OBJECT
public:
UdpServer(QWidget *parent = 0,Qt::WindowFlags f=0);
~UdpServer();
public slots:
void StartBtnClicked();
void timeout();
private:
QLabel *TimerLabel;
QLineEdit *TextLineEdit;
QPushButton *StartBtn;
QVBoxLayout *mainLayout;
int port;
bool isStarted;
QUdpSocket *udpSocket;
QTimer *timer;
};
#endif // UDPSERVER_H
Udpserver.h文件
#include "udpserver.h"
#include <QHostAddress>
UdpServer::UdpServer(QWidget *parent,Qt::WindowFlags f)
: QDialog(parent,f)
{
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 UdpServer::StartBtnClicked()
{
if(!isStarted)//判斷語句,若是爲真的話
{
StartBtn->setText(tr("中止"));
timer->start(1000);//以1000毫秒爲週期啓動計時器(1秒=1000毫秒)
isStarted =true;
}
else
{
StartBtn->setText(tr("開始"));
isStarted = false;
timer->stop();
}
}
void UdpServer::timeout()
{
QString msg = TextLineEdit->text();//把TextLineEdit的內容賦給msg
int length=0;
if(msg=="")//判斷,若是msg爲空的話
{
return;
}
if((length=udpSocket->writeDatagram(msg.toLatin1(),
msg.length(),QHostAddress::Broadcast,port))!=msg.length())//QHostAddress::Broadcast ?
{
return;
}
}
UdpServer::~UdpServer()
{
}
知識點1:if(!)
if( !a )就是一個判斷語句,判斷表達式 !a 的真假,進而決定是否執行後續操做。若是a是一個變量,當a等於0時,!a=1(爲真),執行後續操做;當a不等於0時,!a=0(爲假),不執行後續操做;若是a是一個表達式,將表達式的值計算出來,當成變量來操做,判斷過程同上。
知識點2:writeDatagram(msg.toLatin1(),msg.length(),QHostAddress::Broadcast,port)
qint64 QUdpSocket::writeDatagram(const char *data, qint64 size, const QHostAddress &address, quint16 port) 以大小爲size的數據報發送到端口port的主機地址address。 返回成功發送的字節數; 不然返回-1。
知識點3:信號與槽
1表明要發射信號的類2.表明該類觸發的某一個信號,3表明要觸發槽的類,4表明要觸發類的槽函數
五、 客戶端編程
Udpclient.cpp文件
#ifndef UDPCLIENT_H
#define UDPCLIENT_H
#include <QDialog>
#include <QVBoxLayout>
#include <QTextEdit>
#include <QPushButton>
#include <QUdpSocket>
class UdpClient : public QDialog
{
Q_OBJECT
public:
UdpClient(QWidget *parent = 0,Qt::WindowFlags f=0);
~UdpClient();
public slots:
void CloseBtnClicked();
void dataReceived();
private:
QTextEdit *ReceiveTextEdit;
QPushButton *CloseBtn;
QVBoxLayout *mainLayout;
int port;
QUdpSocket *udpSocket;
};
#endif // UDPCLIENT_H
udpclient.h文件
#include "udpclient.h"
#include <QMessageBox>
#include <QHostAddress>
UdpClient::UdpClient(QWidget *parent,Qt::WindowFlags f)
: QDialog(parent,f)
{
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(CloseBtnClicked()));
port =5555; //設置UDP的端口號參數,指定在此端口上監聽數據
udpSocket = new QUdpSocket(this); //建立一個QUdpSocket
connect(udpSocket,SIGNAL(readyRead()),this,SLOT(dataReceived()));
//鏈接QIODevice的readyRead()信號,QUdpSocket是I/O設備,當數據到達時,發出readyRead()信號
bool result=udpSocket->bind(port); //綁定到指定的端口上
if(!result)//判斷爲假時
{
QMessageBox::information(this,tr("error"),tr("udp socket create error!"));//打開帶有給定標題error和文本的信息udp socket create error!消息框。
return;
}
}
void UdpClient::CloseBtnClicked()
{
close();
}
void UdpClient::dataReceived()
{
while(udpSocket->hasPendingDatagrams())//判斷UdpSocket中是否有數據報可讀,hasPendingDatagrams()在至少有一個數據報可讀時返回true,不然返回false
{
QByteArray datagram;
datagram.resize(udpSocket->pendingDatagramSize());
udpSocket->readDatagram(datagram.data(),datagram.size());
//讀取數據報
QString msg=datagram.data();
ReceiveTextEdit->insertPlainText(msg); //insertPlainText()插入純文本,顯示數據內容
}
}
UdpClient::~UdpClient()
{
}