該程序為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、允許其他服務綁定同樣的地址和端口。 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
|