




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
Qt應用程序開發(fā)Qt4程序設計根底QtDesigner應用QMainWindow、QDialog、LayoutQt4數(shù)據(jù)庫應用Qt4多線程應用Qt4定時器Qt4事件處理Qt4網(wǎng)絡編程QSS樣式設計QGraphicsView應用自定義控件Qt4網(wǎng)絡編程網(wǎng)絡模塊簡介HTTP編程
FTP編程獲取本機網(wǎng)絡信息
UDP編程TCP編程1網(wǎng)絡模塊簡介在Qt中提供了網(wǎng)絡模塊〔QtNetworkModule〕來用于網(wǎng)絡程序的開發(fā),在網(wǎng)絡模塊提供了多個相關類。用于FTP編程的QFtp類,用于HTTP編程的QNetworkAccessManager類和QNetworkReply類,用于獲得本機信息的QHostInfo類,用于Tcp編程的QTcpServer類和QTcpSocket類,用于UDP編程的QUdpSocket類,用于網(wǎng)絡加密的QSslSocket類,用于網(wǎng)絡代理的QNetworkProxy類等等。包含頭文件:#include<QtNetwork>在.pro文件中參加:QT+=network1網(wǎng)絡模塊簡介2HTTP編程?HTTP即超文本傳輸協(xié)議,它是一種文件傳輸協(xié)議。Qt中使用QNetworkAccessManager類和QNetworkReply類來進行HTTP的編程。可以利用HTTP從網(wǎng)站上下載文件。QNetworkAccessManager類實現(xiàn)應用程序發(fā)送網(wǎng)絡請求和接收回應的數(shù)據(jù)。實例化QNetworkAccessManager對象后,利用該對象發(fā)送網(wǎng)絡請求,每次的請求后都會返回一個QNetworkReply對象.這個對象能夠根據(jù)相應的請求來獲得任何返回的數(shù)據(jù)。例如: QNetworkAccessManager*manager=newQNetworkAccessManager(this); connect(manager,SIGNAL(finished(QNetworkReply*)),this, SLOT(replyFinished(QNetworkReply*))); manager->")));QNetworkAccessManager有異步的API.如上例中當replyFinished()插槽被調用時,附帶著QNetworkReply對象,同時包含著下載的數(shù)據(jù)等。2HTTP編程QNetworkAccessManager公有方法QNetworkReply
*QNetworkAccessManager::get(const
QNetworkRequest
&
request
)說明:發(fā)送一個請求來獲得請求的內容,該方法返回一個QNetworkReply對象,并隨時讀取當有新數(shù)據(jù)到達時所發(fā)射的readyRead()信號。請求的內容及標題就會被下載。QNetworkAccessManager信號voidQNetworkAccessManager::finished(
QNetworkReply
*
reply
)說明:只要發(fā)送請求成功,它就會下載數(shù)據(jù),而當數(shù)據(jù)下載完成后,該信號就會被發(fā)射。注意:在request完成后,在適當?shù)臅r候要刪除QNetworkReply對象,但是不要在與finished()信號相連接的插槽刪除該對象,可以利用deleteLater()方法來刪除。2HTTP編程注意:QNetworkAccessManager把接收到的所有request都放到一個隊列中.并行被執(zhí)行的request數(shù)目依賴于協(xié)議。目前HTTP協(xié)議在桌面平臺針對一個主機端口支持同時執(zhí)行6個request。例子:QNetworkRequestrequest;request.setUrl(QUrl(":"));request.setRawHeader("User-Agent","MyOwnBrowser1.0");QNetworkReply*reply=manager->get(request);connect(reply,SIGNAL(readyRead()),this,SLOT(slotReadyRead()));connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(slotError(QNetworkReply::NetworkError)));connect(reply,SIGNAL(sslErrors(QList<QSslError>)),this,SLOT(slotSslErrors(QList<QSslError>)));2HTTP編程QNetworkReply類信號voidQIODevice::readyRead()
[signal]QNetworkReply類是由QIODevice類派生過來的。readyRead()信號是QIODevice類所有的,每次從設備讀取的新數(shù)據(jù)到達時,該信號就會被發(fā)射。當有新數(shù)據(jù)追加到設備時,該信號會再次發(fā)射。而當還有數(shù)據(jù)在緩沖區(qū)等待讀取的時候,該信號就不會被發(fā)射。voidQNetworkReply::error(
QNetworkReply::NetworkError
code
)
[signal]當reply探測到在處理過程中有錯誤的時候,該信號就會被發(fā)射。同時finished()信號也會跟隨被發(fā)射,說明該請求連接結束。code參數(shù)指定錯誤的代碼,可以通過errorString()方法來獲取具體的錯誤信息。voidQNetworkReply::sslErrors(const
QList<QSslError>&
errors
)
[signal]在SSL/TLSsession建立時如果遇到錯誤,該信號就會被發(fā)射,如當證書驗證錯誤等。Errors參數(shù)包含了錯誤的列表。2HTTP編程QNetworkReply類信號voidQNetworkReply::downloadProgress(
qint64
bytesReceived,
qint64
bytesTotal
)
[signal]該信號被發(fā)射來說明網(wǎng)絡請求數(shù)據(jù)下載的進度。QNetworkReply類公有成員QByteArray
QIODevice::readAll()這是個重載的方法,從設備中讀取所有的下載數(shù)據(jù)。返回類型為QByteArray.當QByteArray()為空時,說明設備中沒有可供讀取的數(shù)據(jù),或者在讀取過程中出現(xiàn)了錯誤。2HTTP編程-例子例子:實現(xiàn)簡單的應用HTTP協(xié)議下載網(wǎng)頁的程序。QNetworkAccessManager類用于發(fā)送網(wǎng)絡請求和接收回復,具體的是用QNetworkRequest類來管理請求,QNetworkReply類進行接收回復,并對數(shù)據(jù)進行處理。參考代碼如下:2HTTP編程-例子Widget.h代碼如下:classWidget:publicQWidget{Q_OBJECTpublic:Widget(QWidget*parent=0);~Widget();protected:voidchangeEvent(QEvent*e);private:Ui::Widget*ui;
QNetworkAccessManager*manager;privateslots:
voidreplyFinished(QNetworkReply*);};2HTTP編程-例子Widget.cpp代碼如下:Widget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui->setupUi(this);this->manager=newQNetworkAccessManager(this);connect(this->manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(replyFinished(QNetworkReply*)));this->manager->")));}voidWidget::replyFinished(QNetworkReply*reply){QTextCodec*codec=QTextCodec::codecForName("GB18030");QStringall=codec->toUnicode(reply->readAll());this->ui->textBrowser->setText(all);reply->deleteLater();}2HTTP編程-例子2功能:在上次例子的根底上,實現(xiàn)下載文件的功能,并能顯示下載進度。2HTTP編程-例子2Widget.h代碼如下:classWidget:publicQWidget{Q_OBJECTpublic:Widget(QWidget*parent=0);~Widget();voidstartRequest(QUrlurl);//請求鏈接private:Ui::Widget*ui;QNetworkAccessManager*manager;QNetworkReply*reply;QUrlurl;//存儲網(wǎng)絡地址QFile*file;//文件指針privateslots:voidon_pushButton_clicked();//下載按鈕的單擊事件槽函數(shù)voidFinished();//完成下載后的處理voidReadyRead();//接收到數(shù)據(jù)時的處理voidupdateDataReadProgress(qint64,qint64);//更新進度條};2HTTP編程-例子2Widget.cpp代碼如下:#include"widget.h"#include"ui_widget.h"#include"QFileInfo"#include"QDebug"#include"QNetworkRequest“Widget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui->setupUi(this);this->manager=newQNetworkAccessManager();this->ui->progressBar->hide();}2HTTP編程-例子2Widget.cpp代碼如下:voidWidget::on_pushButton_clicked(){url=ui->lineEdit->text();QFileInfoinfo(url.path());QStringfileName(info.fileName()); //獲取文件名if(fileName.isEmpty())fileName="index.html"; file=newQFile(fileName);if(!file->open(QIODevice::WriteOnly)){//如果翻開文件失敗,那么刪除file,并使file指針為0,然后返回qDebug()<<"fileopenerror";deletefile;file=0;return; }startRequest(url);//進行鏈接請求ui->progressBar->setValue(0);//進度條的值設為0ui->progressBar->show();//顯示進度條}2HTTP編程-例子2Widget.cpp代碼如下:voidWidget::startRequest(QUrlurl){reply=manager->get(QNetworkRequest(url));//下面關聯(lián)信號和槽connect(reply,SIGNAL(finished()),this,SLOT(Finished()));//下載完成后connect(reply,SIGNAL(readyRead()),this,SLOT(ReadyRead()));//有可用數(shù)據(jù)時connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(updateDataReadProgress(qint64,qint64)));//更新進度條}voidWidget::ReadyRead(){if(file)file->write(reply->readAll());//如果文件存在,那么寫入文件}2HTTP編程-例子2Widget.cpp代碼如下:voidWidget::updateDataReadProgress(qint64bytesRead,qint64totalBytes){ui->progressBar->setMaximum(totalBytes);//最大值ui->progressBar->setValue(bytesRead);//當前值}voidWidget::Finished(){ui->progressBar->hide();file->flush();file->close();this->reply->deleteLater();reply=0;deletefile;file=0;}3FTP編程?FTP即FileTransferProtocol,也就是文件傳輸協(xié)議。FTP的主要作用,就是讓用戶連接上一個遠程計算機,查看遠程計算機有哪些文件,然后把文件從遠程計算機上拷貝到本地計算機,或者把本地計算機的文件送到遠程計算機上。在Qt中,我們可以使用QNetworkAccessManager和QNetworkReply類來進行FTP程序的編寫。但是,對于較復雜的FTP操作,Qt還提供了QFtp類。
在QFtp中,所有的操作都對應一個特定的函數(shù),我們可以稱它們?yōu)槊睢H鏲onnectToHost()連接到效勞器命令,login()登錄命令,get()下載命令,mkdir()新建目錄命令等。?QFtp類以異步方式工作,所有的這些函數(shù)都不是阻塞函數(shù)。也就是說,如果一個操作不能立即執(zhí)行,那么這個函數(shù)就會直接返回,直到程序控制權返回Qt事件循環(huán)后才真正執(zhí)行,它們不會影響界面的顯示。3FTP編程所有的命令都返回一個int型的編號,使用這個編號讓我們可以跟蹤這個命令,查看其執(zhí)行狀態(tài)。每條命令開始執(zhí)行時,都會發(fā)出commandStarted()信號,該命令執(zhí)行結束時,會發(fā)出commandFinished()信號??梢岳眠@兩個信號和命令的編號來獲取命令的執(zhí)行狀態(tài)??梢允褂胏urrentCommand()獲取現(xiàn)在執(zhí)行的命令,其返回值與命令對應關系如以下圖。3FTP編程-例子1?在這個例子中我們從FTP效勞器上下載一個文件并顯示出來。3FTP編程-例子1?Widget.h頭文件#include<QWidget>#include"QFtp"classWidget:publicQWidget{Q_OBJECTpublic:Widget(QWidget*parent=0);~Widget();protected:voidchangeEvent(QEvent*e);private:Ui::Widget*ui;QFtp*ftp;privateslots:voidftpCommandStarted(int);voidftpCommandFinished(int,bool);};
3FTP編程-例子1?Widget.cpp參考代碼Widget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui->setupUi(this);ftp=newQFtp(this);ftp->");//連接到效勞器ftp->login();//登錄ftp->cd("qt");//跳轉到“qt”目錄下ftp->get("INSTALL");//下載“INSTALL”文件ftp->close();//關閉連接connect(ftp,SIGNAL(commandStarted(int)),this,SLOT(ftpCommandStarted(int)));//當每條命令開始執(zhí)行時發(fā)出相應的信號connect(ftp,SIGNAL(commandFinished(int,bool)),this,SLOT(ftpCommandFinished(int,bool)));//當每條命令執(zhí)行結束時發(fā)出相應的信號}3FTP編程-例子1?Widget.cpp參考代碼voidWidget::ftpCommandStarted(int){if(ftp->currentCommand()==QFtp::ConnectToHost){ui->label->setText(tr("正在連接到效勞器…"));}if(ftp->currentCommand()==QFtp::Login){ui->label->setText(tr("正在登錄…"));}if(ftp->currentCommand()==QFtp::Get){ui->label->setText(tr("正在下載…"));}elseif(ftp->currentCommand()==QFtp::Close){ui->label->setText(tr("正在關閉連接…"));}}3FTP編程-例子1?Widget.cpp參考代碼voidWidget::ftpCommandFinished(int,boolerror){if(ftp->currentCommand()==QFtp::ConnectToHost){if(error)ui->label->setText(tr("連接效勞器出現(xiàn)錯誤:%1").arg(ftp->errorString()));elseui->label->setText(tr("連接到效勞器成功"));}if(ftp->currentCommand()==QFtp::Login){if(error)ui->label->setText(tr("登錄出現(xiàn)錯誤:%1").arg(ftp->errorString()));elseui->label->setText(tr("登錄成功"));}if(ftp->currentCommand()==QFtp::Get){if(error)ui->label->setText(tr("下載出現(xiàn)錯誤:%1").arg(ftp->errorString()));else{ui->label->setText(tr("已經完成下載"));ui->textBrowser->setText(ftp->readAll());}}elseif(ftp->currentCommand()==QFtp::Close){ui->label->setText(tr("已經關閉連接"));}}3FTP編程-例子2?該例子將例子1程序進行擴展,使其可以瀏覽并能下載效勞器上的所有文件。實現(xiàn)在用戶填寫完相關信息后,按下“連接”按鈕,就可以連接到FTP效勞器,并在TreeWidget中顯示效勞器上的所有文件,我們可以按下“下載”按鈕來下載選中的文件,并使用進度條顯示下載進度3FTP編程-例子2privateslots:voidon_downloadButton_clicked();voidon_cdToParentButton_clicked();voidon_connectButton_clicked();voidftpCommandFinished(int,bool);voidftpCommandStarted(int);voidupdateDataTransferProgress(qint64,qint64);//更新進度條voidaddToList(constQUrlInfo&urlInfo);//將效勞器上的文件添加到TreeWidget中voidprocessItem(QTreeWidgetItem*,int);//雙擊一個目錄時顯示其內容};Widget.h代碼如下:#include<QWidget>#include"QUrlInfo"#include"QTreeWidgetItem"#include"QFtp“#include”QFile”classWidget:publicQWidget{Q_OBJECTpublic:Widget(QWidget*parent=0);~Widget();protected:voidchangeEvent(QEvent*e);private:Ui::Widget*ui;QHash<QString,bool>isDirectory;QStringcurrentPath;QFtp*ftp;QFile*file;3FTP編程-例子2Widget.cpp代碼如下:#include"widget.h"#include"ui_widget.h"#include"QFtp"#include"QPixmap"#include"QFile"Widget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui->setupUi(this);ui->progressBar->setValue(0);connect(ui->fileList,SIGNAL(itemActivated(QTreeWidgetItem*,int)),this,SLOT(processItem(QTreeWidgetItem*,int)));//鼠標雙擊列表中的目錄時,我們進入該目錄}3FTP編程-例子2Widget.cpp代碼如下:voidWidget::on_connectButton_clicked(){ui->fileList->clear();currentPath.clear();isDirectory.clear();ftp=newQFtp(this);connect(ftp,SIGNAL(commandStarted(int)),this,SLOT(ftpCommandStarted(int)));connect(ftp,SIGNAL(commandFinished(int,bool)),this,SLOT(ftpCommandFinished(int,bool)));connect(ftp,SIGNAL(listInfo(QUrlInfo)),this,SLOT(addToList(QUrlInfo)));connect(ftp,SIGNAL(dataTransferProgress(qint64,qint64)),this,SLOT(updateDataTransferProgress(qint64,qint64)));QStringftpServer=this->ui->ftpServerlineEdit->text();QStringuserName=this->ui->userNamelineEdit->text();QStringpassWord=this->ui->passWordlineEdit->text();ftp->connectToHost(ftpServer,21);//連接到效勞器,默認端口號是21ftp->login(userName,passWord);//登錄}3FTP編程-例子2Widget.cpp代碼如下:voidWidget::ftpCommandStarted(int){if(ftp->currentCommand()==QFtp::ConnectToHost){ui->label->setText(tr("正在連接到效勞器…"));}if(ftp->currentCommand()==QFtp::Login){ui->label->setText(tr("正在登錄…"));}if(ftp->currentCommand()==QFtp::Get){ui->label->setText(tr("正在下載…"));}elseif(ftp->currentCommand()==QFtp::Close){ui->label->setText(tr("正在關閉連接…"));}}3FTP編程-例子2Widget.cpp代碼如下:voidWidget::ftpCommandFinished(int,boolerror){if(ftp->currentCommand()==QFtp::Login){if(error)ui->label->setText(tr("登錄出現(xiàn)錯誤:%1").arg(ftp->errorString()));else{ui->label->setText(tr("登錄成功"));this->ftp->list();}}if(ftp->currentCommand()==QFtp::Get){if(error)ui->label->setText(tr("下載出現(xiàn)錯誤:%1").arg(ftp->errorString()));else{ui->label->setText(tr("已經完成下載"));this->ui->downloadButton->setEnabled(true); this->file.close();}}if(ftp->currentCommand()==QFtp::List){if(isDirectory.isEmpty()){//如果目錄為空,顯示“empty”ui->fileList->addTopLevelItem(newQTreeWidgetItem(QStringList()<<tr("<empty>")));ui->fileList->setEnabled(false);ui->label->setText(tr("該目錄為空"));}}}3FTP編程-例子2Widget.cpp代碼如下:voidWidget::processItem(QTreeWidgetItem*item,int){QStringname=item->text(0);//返回第0列的文本值if(isDirectory.value(name)){//如果這個文件是個目錄,那么翻開ui->fileList->clear();isDirectory.clear();currentPath+='/';currentPath+=name;ftp->cd(name);ftp->list();ui->cdToParentButton->setEnabled(true);}}3FTP編程-例子2Widget.cpp代碼如下:voidWidget::on_cdToParentButton_clicked(){ui->fileList->clear();isDirectory.clear();currentPath=currentPath.left(currentPath.lastIndexOf('/'));if(currentPath.isEmpty()){ui->cdToParentButton->setEnabled(false);ftp->cd("/");}else{ftp->cd(currentPath);}ftp->list();}voidWidget::on_downloadButton_clicked(){QStringfileName=ui->fileList->currentItem()->text(0);this->file=newQFile(fileName);if(!file->open(QIODevice::WriteOnly)){deletefile;return;}ui->downloadButton->setEnabled(false);//下載按鈕不可用,等下載完成后才可用
ftp->get(ui->fileList->currentItem()->text(0),file);}3FTP編程-例子2Widget.cpp代碼如下:voidWidget::addToList(constQUrlInfo&urlInfo){ QTreeWidgetItem*item=newQTreeWidgetItem;item->setText(0,urlI());item->setText(1,QString::number(urlInfo.size()));item->setText(2,urlInfo.owner());item->setText(3,urlInfo.group());item->setText(4,urlInfo.lastModified().toString("MMMddyyyy"));QPixmappixmap(urlInfo.isDir()?"../dir.png":"../file.png");item->setIcon(0,pixmap);isDirectory[urlI()]=urlInfo.isDir();//存儲該路徑是否為目錄的信息
ui->fileList->addTopLevelItem(item);if(!ui->fileList->currentItem()){ui->fileList->setCurrentItem(ui->fileList->topLevelItem(0));ui->fileList->setEnabled(true);}}voidWidget::updateDataTransferProgress(qint64readBytes,qint64totalBytes){ui->progressBar->setMaximum(totalBytes);ui->progressBar->setValue(readBytes);}4獲取本機網(wǎng)絡信息?如果要獲取自己電腦的IP地址以及其他網(wǎng)絡信息。會涉及到網(wǎng)絡模塊〔QtNetworkModule〕中的QHostInfo,QHostAddress,QNetworkInterface和QNetworkAddressEntry等類?!?〕使用QHostInfo獲取主機名和IP地址獲取主機名字:QHostInfo::localHostName()獲取IP地址: QHostInfoinfo=QHostInfo::fromName(localHostName); qDebug()<<”IPAddress:“<<info.addresses();〔2〕通過QNetworkInterface類來獲取本機的IP地址和網(wǎng)絡接口信息QNetworkInterface類提供了程序所運行時的主機的IP地址和網(wǎng)絡接口信息的列表。在每一個網(wǎng)絡接口信息中都包含了0個或多個IP地址,而每一個IP地址又包含了和它相關的子網(wǎng)掩碼和播送地址,它們三者被封裝在一個QNetworkAddressEntry對象中。網(wǎng)絡接口信息中也提供了硬件地址信息。4獲取本機網(wǎng)絡信息?QList<QNetworkInterface>list=QNetworkInterface::allInterfaces();//獲取所有網(wǎng)絡接口的列表foreach(QNetworkInterfaceinterface,list)//遍歷每一個網(wǎng)絡接口{qDebug()<<"Device:"<<();//設備名qDebug()<<"HardwareAddress:"<<interface.hardwareAddress();//硬件地址QList<QNetworkAddressEntry>entryList=interface.addressEntries();//獲取IP地址條目列表,每個條目中包含一個IP地址,一個子網(wǎng)掩碼和一個播送地址foreach(QNetworkAddressEntryentry,entryList)//遍歷每一個IP地址條目{qDebug()<<"IPAddress:"<<entry.ip().toString();//IP地址qDebug()<<"Netmask:"<<mask().toString();//子網(wǎng)掩碼qDebug()<<"Broadcast:"<<entry.broadcast().toString();//播送地址}}4獲取本機網(wǎng)絡信息?常用的獲取IP地址的方法:QStringWidget::getIP()
//獲取ip地址
{
QList<QHostAddress>list=QNetworkInterface::allAddresses();
foreach(QHostAddressaddress,list)
{
if(tocol()==QAbstractSocket::IPv4Protocol)
returnaddress.toString();
}
return0;
}5UDP編程?UDP〔UserDatagramProtocol即用戶數(shù)據(jù)報協(xié)議〕是一個輕量級的,不可靠的,面向數(shù)據(jù)報的無連接協(xié)議。騰訊QQ,其聊天時就是使用UDP協(xié)議進行消息發(fā)送的。就像QQ那樣,當有很多用戶,發(fā)送的大局部都是短消息,要求能及時響應,并且對平安性要求不是很高的情況下使用UDP協(xié)議。在Qt中提供了QUdpSocket類來進行UDP數(shù)據(jù)報〔datagrams〕的發(fā)送和接收。這里我們還要了解一個名詞Socket,也就是常說的“套接字”。Socket簡單地說,就是一個IP地址加一個port端口。因為我們要傳輸數(shù)據(jù),就要知道往哪個機子上傳送,而IP地址確定了一臺主機,但是這臺機子上可能運行著各種各樣的網(wǎng)絡程序,我們要往哪個程序中發(fā)送呢?這時就要使用一個端口來指定UDP程序。所以說,Socket指明了數(shù)據(jù)報傳輸?shù)穆窂健?UDP編程?例子:編寫兩個程序,一個用來發(fā)送數(shù)據(jù)報,可以叫做客戶端;另一個用來接收數(shù)據(jù)報,可以叫做效勞器端,它們均應用UDP協(xié)議。這樣也就構成了所謂的C/S〔客戶端/效勞器〕編程模型。客戶端的界面如以下圖:5UDP編程?“開始播送”按鈕的單擊事件槽函數(shù):voidWidget::on_pushButton_clicked()
//發(fā)送播送{
QByteArraydatagram=“helloworld!”;
sender->writeDatagram(datagram.data(),datagram.size(),
QHostAddress::Broadcast,45454);}這里我們定義了一個QByteArray類型的數(shù)據(jù)報datagram,其內容為“helloworld!”。然后使用QUdpSocket類的writeDatagram()函數(shù)來發(fā)送數(shù)據(jù)報,這個函數(shù)有四個參數(shù),分別是數(shù)據(jù)報的內容,數(shù)據(jù)報的大小,主機地址和端口號。對于數(shù)據(jù)報的大小,它根據(jù)平臺的不同而不同,但是這里建議不要超過512字節(jié)。這里我們使用了播送地址QHostAddress::Broadcast,這樣就可以同時給網(wǎng)絡中所有的主機發(fā)送數(shù)據(jù)報了。對于端口號,它是可以隨意指定的,但是一般1024以下的端口號通常屬于保存端口號,所以我們最好使用大于1024的端口,最大為65535。我們這里使用了45454這個端口號,一定要注意,在下面要講的效勞器程序中,也要使用相同的端口號。5UDP編程?效勞器端的界面如以下圖:receiver=newQUdpSocket(this);receiver->bind(45454,QUdpSocket::ShareAddress);connect(receiver,SIGNAL(readyRead()),this,SLOT(processPendingDatagram()));構造函數(shù)中將receiver綁定到45454端口,這個端口就是上面發(fā)送端設置的端口,二者必須一樣才能保證接收到數(shù)據(jù)報。我們這里使用了綁定模式QUdpSocket::ShareAddress,它說明其他效勞也可以綁定到這個端口上。當receiver發(fā)現(xiàn)有數(shù)據(jù)報到達時就會發(fā)出readyRead()信號,將其和數(shù)據(jù)報處理函數(shù)相關聯(lián)。5UDP編程?voidWidget::processPendingDatagram()//處理等待的數(shù)據(jù)報{while(receiver->hasPendingDatagrams())//擁有等待的數(shù)據(jù)報
{QByteArraydatagram;//擁于存放接收的數(shù)據(jù)報
datagram.resize(receiver->pendingDatagramSize());//讓datagram的大小為等待處理的數(shù)據(jù)報的大小,這樣才能接收到完整的數(shù)據(jù)
receiver->readDatagram(datagram.data(),datagram.size());//接收數(shù)據(jù)報,將其存放到datagram中
ui->label->setText(datagram);//將數(shù)據(jù)報內容顯示出來
}}5UDP編程?先運行效勞器端程序,再運行客戶端程序。然后點擊其上的“發(fā)送播送”按鈕,這時會顯示數(shù)據(jù)報的內容??梢钥吹剑琔DP的應用是很簡單的。我們只需要在發(fā)送端執(zhí)行writeDatagram()函數(shù)進行數(shù)據(jù)報的發(fā)送,然后在接收端綁定端口,并關聯(lián)readyRead()信號和數(shù)據(jù)報處理函數(shù)即可。改程序運行效果如以下圖:5UDP編程?例子:聊天程序:5UDP編程?參考代碼如下:Widget.hclassWidget:publicQWidget{Q_OBJECTpublic:Widget(QWidget*parent=0);~Widget();voidsendmessage();QStringgetIP();QStringgetmessage();protected:voidchangeEvent(QEvent*e);private:Ui::Widget*ui;QUdpSocket*udpsocket;privateslots:voidon_SendpushButton_clicked();voidprocesspendingdatagram();};5UDP編程?參考代碼如下:Widget.cppWidget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui->setupUi(this);this->ui->lineEdit->setFocus();this->udpsocket=newQUdpSocket(this);this->udpsocket->bind(45454,QUdpSocket::ShareAddress|QUdpSocket::ReuseAddressHint);connect(this->udpsocket,SIGNAL(readyRead()),this,SLOT(processpendingdatagram()));}5UDP編程?參考代碼如下:Widget.cppvoidWidget::on_SendpushButton_clicked(){sendmessage();}voidWidget::sendmessage(){QByteArraydata;QDataStreamout(&data,QIODevice::WriteOnly);QStringlocalhostname=QHostInfo::localHostName();QStringaddress=this->getIP();out<<localhostname<<address<<getmessage();this->udpsocket->writeDatagram(data,data.length(),QHostAddress::Broadcast,45454);}5UDP編程?參考代碼如下:Widget.cppQStringWidget::getIP(){QList<QHostAddress>list=QNetworkInterface::allAddresses();foreach(QHostAddressaddress,list){if(tocol()==QAbstractSocket::IPv4Protocol)
returnaddress.toString();}return0;}QStringWidget::getmessage()//獲得要發(fā)送的信息{QStringmsg=this->ui->lineEdit->text();ui->lineEdit->clear();ui->lineEdit->setFocus();returnmsg;}5UDP編程?參考代碼如下:Widget.cppvoidWidget::processpendingdatagram(){while(this->udpsocket->hasPendingDatagrams()){QByt
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 人教版九年級化學上冊第四單元課題2水的凈化教學設計
- 六年級數(shù)學上冊 四 百分數(shù)第5課時 這月我當家(1)配套教學設計 北師大版
- 二年級道德與法治下冊 第一單元 讓我試試看 第2課《學做快樂鳥》教學設計1 新人教版
- 2024中國移動新疆公司招聘37人筆試參考題庫附帶答案詳解
- 地鐵安檢人員培訓大綱
- 高級卷煙包裝工專業(yè)知識復習題練習試卷附答案
- 《百分數(shù)的應用(二)》(教學設計)-2024-2025學年北師大版小學數(shù)學六年級上冊
- 安徽省合肥市廬江縣湯池鎮(zhèn)初級中學2023-2024學年八年級下學期期中數(shù)學試題
- 山東省濰坊市2024-2025學年八年級下學期期中數(shù)學試卷(原卷版+解析版)
- 大氣環(huán)境生態(tài)恢復重點基礎知識點
- 危險品安全教育培訓總結報告
- 基于STM32點陣電子顯示屏
- 幼兒園社會課件:小鏡頭大世界
- TZAFT 4001.2-2023 金融科技人才職業(yè)能力建設與評估指引(技術研發(fā)類人才)
- 世界近代武器革新圖鑒(1722-1900)英國篇
- 系統(tǒng)安全運維培訓內容
- 新時代社區(qū)治理存在的問題及對策研究-以XX社區(qū)為例
- 《西方經濟學》說課
- 安標受控件采購管理制度
- 《針灸神奇作用》課件
- 美國醫(yī)療的社會變遷
評論
0/150
提交評論