Qt之UDP編程實驗(1)


該程序為QT自帶Demo,工程名為broadcast receiver,展示了在一個如何在本地局域網中接收UDP廣播的信息。

broadcastreceiver.pro

 HEADERS       = receiver.h
 SOURCES       = receiver.cpp \
                 main.cpp
 QT           += network

receiver.h

#ifndef RECEIVER_H
#define RECEIVER_H

#include<QWidget>

class QLabel;
class QPushButton;
class QUdpSocket;

class Receiver:public QWidget
{
    Q_OBJECT
public:
    Receiver(QWidget *parent=0);

private slots:
void processPendingDatagrams();

private:
    QLabel *statusLabel;
    QPushButton *quitButton;
    QUdpSocket *udpSocket;
};


#endif // RECEIVER_H

receiver.cpp

#include<QtGui>
#include<QtNetwork>

#include"receiver.h"

Receiver::Receiver(QWidget *parent):QWidget(parent)
{
    statusLabel=new QLabel(tr("Listening for broadcasted messages"));
    statusLabel->setWordWrap(true);//設置為可換行
    quitButton=new QPushButton(tr("&Quit"));

    udpSocket=new QUdpSocket(this);
    
    /*QUdpSocket::ShareAddress表明其他服務也可以綁定在這個端口上*/
    udpSocket->bind(45454, QUdpSocket::ShareAddress);

    connect(udpSocket,SIGNAL(readyRead()),this,SLOT(processPendingDatagram()));
    connect(quitButton,SIGNAL(clicked()),this,SLOT(close()));

    QHBoxLayout *buttonLayout=new QHBoxLayout();
    buttonLayout->addStretch(1);
    buttonLayout->addWidget(quitButton);
    buttonLayout->addStretch(1);

    QVBoxLayout *mainLayout=new QVBoxLayout();
    mainLayout->addWidget(statusLabel);
    mainLayout->addLayout(buttonLayout);
    setLayout(mainLayout);

    setWindowTitle(tr("Receiver"));


}

void Receiver::processPendingDatagrams()
{
    while(udpSocket->hasPendingDatagrams())
    {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());
        udpSocket->readDatagram(datagram.data(),datagram.size());
        statusLabel->setText(tr("Received datagram:\"%1\"").arg(datagram.data()));
    }
}

main.cpp

#include<QApplication>
#include"receiver.h"

int main(int argc,char *argv[])
{
    QApplication app(argc,argv);
    Receiver receiver;
    receiver.show();
    return app.exec();
}

 運行結果:

 

一、概述:                                           

#include <QUdpSocket>

QUdpSocket類繼承自QAbstractSocket,該類中的所有函數都是可重入的(reentrent)。
 
二、介紹
QUdpSocket描述:
QUdpSocket提供了UDP套接字API,用來接收和發送UDP數據報。
QUdpSocket類最通用的使用方式是:用bind()函數綁定一個IP地址和端口Port,然后調用writeDatagram()和readDatagram()函數傳輸數據。如果要使用QIODevice中的read(), readLine(), write()等函數,必須首先調用connectToHost()函數,直接建立一個和對方的連接。
 
只要向網絡寫入了一個數據報,SOCKET就產生一個bytesWritten()信號,如果僅僅是發送數據報,無需調用bind()。
數據報到來,readyRead()信號被產生,此時hasPendingDatagrams()函數返回真(true)。調用pendingDatagramSize()獲取第一個數據報的長度(size),readDatagram()讀取數據報內容。
 
注意:接收到readyRead()信號后,應當讀取該數據報,否則下一個數據報到來后將不再產生readyRead()信號。
 

QUdpSocket類也支持UPD組播(multicast)。joinMulticastGroup()和leaveMulticastGroup()用來控制組成員,QAbstractSocket::MulticastTtlOption和QAbstractSocket::MulticastLoopbackOption分別用來設置socket的TTL和回環(loopback)選項,setMulticastInterface()用來為組播數據報設置對外接口,multicastInterface()來獲取該接口類型:IP_MULTICAST_IF對應IPv4,IPV6_MULTICAST_IFIPv6。
 
通過QUdpSocket類,還可以使用connectToHost()建立和UDP服務器的虛擬連接,然后使用read()和write()交換數據,而不必為每一個數據報都指定接收者(receiver)。
 
三、標志成員含義
 
BindFlag:
這些值可以組成不同的標志,傳遞給QUdpSocket::bind()函數來修改bind()的特性。
enum   BindFlag {ShareAddress, DontShareAddress, ReuseAddressHint, DefaultForPlatform }
 
常量定義 描述
QUdpSocket::ShareAddress 0x1

1、允許其他服務綁定同樣的地址和端口。
2、當多進程通過監聽同一地址和端口,進而共享單個服務的負載時。將十分有用(例如:一個擁有幾個預先建立的監聽者的WEB服務器能夠改善響應時間)。不過,由於任何服務都允許重新綁定(rebind),該選項應該引起某些安全上的考慮

3、需要注意的是,把該選項和ReuseAddressHint結合,也會允許你的服務重新綁定一個已存在的共享地址

4、在Unix上,該選項等同於SO_REUSEADDR;在Windows上,該選項被忽略

QUdpSocket::DontShareAddress 0x2
1、采用專有的方式綁定某個地址和端口,其他任何服務都不能再重新綁定
2、通過該選項,確保綁定成功,指定的服務將是地址和端口唯一監聽者,就算是擁有ReuseAddressHint的服務也不允許重新綁定
3、在安全性上,該選項優於ShareAddress,但是在某些操作系統上需要管理員的權限才能運行
4、在Unix和Mac OS上,綁定地址和端口的默認行為是非共享,所以該選項會被忽略;在Windows上,等同於SO_EXCLUSIVEADDRUSE套接字選項
QUdpSocket::ReuseAddressHint 0x4  
1、為QUdpSocke提供提示,即在地址和端口已經被其他套接字綁定的情況下,也應該試着重新綁定
2、在Unix上,該選項被忽略;在Windows上等同於SO_REUSEADDR 套接字選項
QUdpSocket::DefaultForPlatform 0x0
1、當前平台的默認選項
2、在Unix和Mac OS上,該選項等同於DontShareAddress + ReuseAddressHint;在Windows上等同於ShareAddress
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM