1. 程式人生 > 其它 >QT學習(網路通訊:UDP)

QT學習(網路通訊:UDP)

技術標籤:QT網路qt5udp

QT學習(網路)

UDP

UDP(UserDatagram Protocol即使用者資料報協議)是一個輕量級的,不可靠的,面向資料報的無連線協議。對於UDP我們不再進行過多介紹,如果你對UDP不是很瞭解,而且不知道它有什麼用,那麼這裡就舉個簡單的例子:我們現在幾乎每個人都使用的騰訊QQ,其聊天時就是使用UDP協議進行訊息傳送的。就像QQ那樣,當有很多使用者,傳送的大部分都是短訊息,要求能及時響應,並且對安全性要求不是很高的情況下使用UDP協議。

在Qt中提供了QUdpSocket 類來進行UDP資料報(datagrams)的傳送和接收。這裡我們還要了解一個名詞Socket,也就是常說的“套接字”。 Socket簡單地說,就是一個IP地址加一個port埠。因為我們要傳輸資料,就要知道往哪個機子上傳送,而IP地址確定了一臺主機,但是這臺機子上可能執行著各種各樣的網路程式,我們要往哪個程式中傳送呢?這時就要使用一個埠來指定UDP程式。所以說,Socket指明瞭資料報傳輸的路徑。

進入程式碼環節

***.pro

QT       += core gui network

介面如下:
在這裡插入圖片描述
在這裡插入圖片描述
***1.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QtNetwork/QtNetwork>
#include <QtNetwork/QUdpSocket>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
    QUdpSocket *sender;
};

#endif // WIDGET_H

***1.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    sender = new QUdpSocket(this);
}

Widget::~Widget()
{
    delete ui;
}

/********************************************************************************************************
    這裡定義了一個QByteArray型別的資料報datagram,其內容為“hello world!”。
    然後使用QUdpSocket類的writeDatagram()函式來發送資料報,這個函式有四個引數,
    分別是資料報的內容,資料報的大小,主機地址和埠號。對於資料報的大小,它根據平臺的不同而不同,
    但是這裡建議不要超過512位元組。這裡使用了廣播地址QHostAddress::Broadcast,這樣就可以同時給網路中所有的主機發送資料報了。
    對於埠號,它是可以隨意指定的,但是一般1024以下的埠號通常屬於保留埠號,所以我們最好使用大於1024的埠,最大為65535。
    我們這裡使用了45454這個埠號,一定要注意,在下面要講的伺服器程式中,也要使用相同的埠號。
 *********************************************************************************************************/
void Widget::on_pushButton_clicked()// 開始廣播 { QByteArray datagram = "hello world!"; sender->writeDatagram(datagram.data(),datagram.size(), QHostAddress::Broadcast,45454); }

***2.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QtNetwork/QtNetwork>
#include <QtNetwork/QUdpSocket>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void processPendingDatagram();

private:
    Ui::Widget *ui;
    QUdpSocket *receiver;
};

#endif // WIDGET_H

***2.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    receiver = new QUdpSocket(this);
    receiver->bind(45454,QUdpSocket::ShareAddress);//將receiver繫結到45454埠,這個埠就是上面傳送端設定的埠,二者必須一樣才能保證接收到資料報。
    connect(receiver,SIGNAL(readyRead()),this,SLOT(processPendingDatagram()));
}

Widget::~Widget()
{
    delete ui;
}


/******************************************************************************************************
    主要用於接收來自udpSender的資料報,所以需要和udpSender同時使用。
    注意事項:第一次執行該程式時,系統可能會提示警告,我們選擇“解除阻止”。 注意,如果是在linux下,你可能還需要關閉防火牆。
********************************************************************************************************/
void Widget::processPendingDatagram() //處理等待的資料報
{
    while(receiver->hasPendingDatagrams())  //擁有等待的資料報
    {
        QByteArray datagram; //擁於存放接收的資料報
        datagram.resize(receiver->pendingDatagramSize());//讓datagram的大小為等待處理的資料報的大小,這樣才能接收到完整的資料
        receiver->readDatagram(datagram.data(),datagram.size());//接收資料報,將其存放到datagram中
        ui->label->setText(datagram);//將資料報內容顯示出來
    }
}

學習連結:
網路Utp