UDP

基于UDPUser Data Protocol,用户数据报协议)的网络广播程序

1、  UDP是一种简单轻量级、不可靠、面向数据报、无连接的传输层协议,可以应用在可靠性不是十分重要的场合,如短消息、广播信息等。

2、  特点

网络数据大多为短消息

拥有大量的客户端

对数据安全性无特殊要求

网络负担非常重要,但对响应速度要求高

3、  UDP客户端与服务器间的交互时序

4、  服务器端编程

udpserver.cpp文件

#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代表要触发类的槽函数        

5、  客户端编程

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()
{
 
}
posted @ 2018-04-12 08:26  王先森的宝宝吴  阅读(199)  评论(0编辑  收藏  举报