Qt應(yīng)用程序開(kāi)發(fā)8_第1頁(yè)
Qt應(yīng)用程序開(kāi)發(fā)8_第2頁(yè)
Qt應(yīng)用程序開(kāi)發(fā)8_第3頁(yè)
Qt應(yīng)用程序開(kāi)發(fā)8_第4頁(yè)
Qt應(yīng)用程序開(kāi)發(fā)8_第5頁(yè)
已閱讀5頁(yè),還剩51頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

Qt應(yīng)用程序開(kāi)發(fā)Qt4程序設(shè)計(jì)根底QtDesigner應(yīng)用QMainWindow、QDialog、LayoutQt4數(shù)據(jù)庫(kù)應(yīng)用Qt4多線程應(yīng)用Qt4定時(shí)器Qt4事件處理Qt4網(wǎng)絡(luò)編程QSS樣式設(shè)計(jì)QGraphicsView應(yīng)用自定義控件Qt4網(wǎng)絡(luò)編程網(wǎng)絡(luò)模塊簡(jiǎn)介HTTP編程

FTP編程獲取本機(jī)網(wǎng)絡(luò)信息

UDP編程TCP編程1網(wǎng)絡(luò)模塊簡(jiǎn)介在Qt中提供了網(wǎng)絡(luò)模塊〔QtNetworkModule〕來(lái)用于網(wǎng)絡(luò)程序的開(kāi)發(fā),在網(wǎng)絡(luò)模塊提供了多個(gè)相關(guān)類。用于FTP編程的QFtp類,用于HTTP編程的QNetworkAccessManager類和QNetworkReply類,用于獲得本機(jī)信息的QHostInfo類,用于Tcp編程的QTcpServer類和QTcpSocket類,用于UDP編程的QUdpSocket類,用于網(wǎng)絡(luò)加密的QSslSocket類,用于網(wǎng)絡(luò)代理的QNetworkProxy類等等。包含頭文件:#include<QtNetwork>在.pro文件中參加:QT+=network1網(wǎng)絡(luò)模塊簡(jiǎn)介2HTTP編程?HTTP即超文本傳輸協(xié)議,它是一種文件傳輸協(xié)議。Qt中使用QNetworkAccessManager類和QNetworkReply類來(lái)進(jìn)行HTTP的編程??梢岳肏TTP從網(wǎng)站上下載文件。QNetworkAccessManager類實(shí)現(xiàn)應(yīng)用程序發(fā)送網(wǎng)絡(luò)請(qǐng)求和接收回應(yīng)的數(shù)據(jù)。實(shí)例化QNetworkAccessManager對(duì)象后,利用該對(duì)象發(fā)送網(wǎng)絡(luò)請(qǐng)求,每次的請(qǐng)求后都會(huì)返回一個(gè)QNetworkReply對(duì)象.這個(gè)對(duì)象能夠根據(jù)相應(yīng)的請(qǐng)求來(lái)獲得任何返回的數(shù)據(jù)。例如: QNetworkAccessManager*manager=newQNetworkAccessManager(this); connect(manager,SIGNAL(finished(QNetworkReply*)),this, SLOT(replyFinished(QNetworkReply*))); manager->")));QNetworkAccessManager有異步的API.如上例中當(dāng)replyFinished()插槽被調(diào)用時(shí),附帶著QNetworkReply對(duì)象,同時(shí)包含著下載的數(shù)據(jù)等。2HTTP編程QNetworkAccessManager公有方法QNetworkReply

*QNetworkAccessManager::get(const

QNetworkRequest

&

request

)說(shuō)明:發(fā)送一個(gè)請(qǐng)求來(lái)獲得請(qǐng)求的內(nèi)容,該方法返回一個(gè)QNetworkReply對(duì)象,并隨時(shí)讀取當(dāng)有新數(shù)據(jù)到達(dá)時(shí)所發(fā)射的readyRead()信號(hào)。請(qǐng)求的內(nèi)容及標(biāo)題就會(huì)被下載。QNetworkAccessManager信號(hào)voidQNetworkAccessManager::finished(

QNetworkReply

*

reply

)說(shuō)明:只要發(fā)送請(qǐng)求成功,它就會(huì)下載數(shù)據(jù),而當(dāng)數(shù)據(jù)下載完成后,該信號(hào)就會(huì)被發(fā)射。注意:在request完成后,在適當(dāng)?shù)臅r(shí)候要?jiǎng)h除QNetworkReply對(duì)象,但是不要在與finished()信號(hào)相連接的插槽刪除該對(duì)象,可以利用deleteLater()方法來(lái)刪除。2HTTP編程注意:QNetworkAccessManager把接收到的所有request都放到一個(gè)隊(duì)列中.并行被執(zhí)行的request數(shù)目依賴于協(xié)議。目前HTTP協(xié)議在桌面平臺(tái)針對(duì)一個(gè)主機(jī)端口支持同時(shí)執(zhí)行6個(gè)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類信號(hào)voidQIODevice::readyRead()

[signal]QNetworkReply類是由QIODevice類派生過(guò)來(lái)的。readyRead()信號(hào)是QIODevice類所有的,每次從設(shè)備讀取的新數(shù)據(jù)到達(dá)時(shí),該信號(hào)就會(huì)被發(fā)射。當(dāng)有新數(shù)據(jù)追加到設(shè)備時(shí),該信號(hào)會(huì)再次發(fā)射。而當(dāng)還有數(shù)據(jù)在緩沖區(qū)等待讀取的時(shí)候,該信號(hào)就不會(huì)被發(fā)射。voidQNetworkReply::error(

QNetworkReply::NetworkError

code

)

[signal]當(dāng)reply探測(cè)到在處理過(guò)程中有錯(cuò)誤的時(shí)候,該信號(hào)就會(huì)被發(fā)射。同時(shí)finished()信號(hào)也會(huì)跟隨被發(fā)射,說(shuō)明該請(qǐng)求連接結(jié)束。code參數(shù)指定錯(cuò)誤的代碼,可以通過(guò)errorString()方法來(lái)獲取具體的錯(cuò)誤信息。voidQNetworkReply::sslErrors(const

QList<QSslError>&

errors

)

[signal]在SSL/TLSsession建立時(shí)如果遇到錯(cuò)誤,該信號(hào)就會(huì)被發(fā)射,如當(dāng)證書(shū)驗(yàn)證錯(cuò)誤等。Errors參數(shù)包含了錯(cuò)誤的列表。2HTTP編程QNetworkReply類信號(hào)voidQNetworkReply::downloadProgress(

qint64

bytesReceived,

qint64

bytesTotal

)

[signal]該信號(hào)被發(fā)射來(lái)說(shuō)明網(wǎng)絡(luò)請(qǐng)求數(shù)據(jù)下載的進(jìn)度。QNetworkReply類公有成員QByteArray

QIODevice::readAll()這是個(gè)重載的方法,從設(shè)備中讀取所有的下載數(shù)據(jù)。返回類型為QByteArray.當(dāng)QByteArray()為空時(shí),說(shuō)明設(shè)備中沒(méi)有可供讀取的數(shù)據(jù),或者在讀取過(guò)程中出現(xiàn)了錯(cuò)誤。2HTTP編程-例子例子:實(shí)現(xiàn)簡(jiǎn)單的應(yīng)用HTTP協(xié)議下載網(wǎng)頁(yè)的程序。QNetworkAccessManager類用于發(fā)送網(wǎng)絡(luò)請(qǐng)求和接收回復(fù),具體的是用QNetworkRequest類來(lái)管理請(qǐng)求,QNetworkReply類進(jìn)行接收回復(fù),并對(duì)數(shù)據(jù)進(jìn)行處理。參考代碼如下: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功能:在上次例子的根底上,實(shí)現(xiàn)下載文件的功能,并能顯示下載進(jìn)度。2HTTP編程-例子2Widget.h代碼如下:classWidget:publicQWidget{Q_OBJECTpublic:Widget(QWidget*parent=0);~Widget();voidstartRequest(QUrlurl);//請(qǐng)求鏈接private:Ui::Widget*ui;QNetworkAccessManager*manager;QNetworkReply*reply;QUrlurl;//存儲(chǔ)網(wǎng)絡(luò)地址QFile*file;//文件指針privateslots:voidon_pushButton_clicked();//下載按鈕的單擊事件槽函數(shù)voidFinished();//完成下載后的處理voidReadyRead();//接收到數(shù)據(jù)時(shí)的處理voidupdateDataReadProgress(qint64,qint64);//更新進(jìn)度條};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)){//如果翻開(kāi)文件失敗,那么刪除file,并使file指針為0,然后返回qDebug()<<"fileopenerror";deletefile;file=0;return; }startRequest(url);//進(jìn)行鏈接請(qǐng)求ui->progressBar->setValue(0);//進(jìn)度條的值設(shè)為0ui->progressBar->show();//顯示進(jìn)度條}2HTTP編程-例子2Widget.cpp代碼如下:voidWidget::startRequest(QUrlurl){reply=manager->get(QNetworkRequest(url));//下面關(guān)聯(lián)信號(hào)和槽connect(reply,SIGNAL(finished()),this,SLOT(Finished()));//下載完成后connect(reply,SIGNAL(readyRead()),this,SLOT(ReadyRead()));//有可用數(shù)據(jù)時(shí)connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(updateDataReadProgress(qint64,qint64)));//更新進(jìn)度條}voidWidget::ReadyRead(){if(file)file->write(reply->readAll());//如果文件存在,那么寫(xiě)入文件}2HTTP編程-例子2Widget.cpp代碼如下:voidWidget::updateDataReadProgress(qint64bytesRead,qint64totalBytes){ui->progressBar->setMaximum(totalBytes);//最大值ui->progressBar->setValue(bytesRead);//當(dāng)前值}voidWidget::Finished(){ui->progressBar->hide();file->flush();file->close();this->reply->deleteLater();reply=0;deletefile;file=0;}3FTP編程?FTP即FileTransferProtocol,也就是文件傳輸協(xié)議。FTP的主要作用,就是讓用戶連接上一個(gè)遠(yuǎn)程計(jì)算機(jī),查看遠(yuǎn)程計(jì)算機(jī)有哪些文件,然后把文件從遠(yuǎn)程計(jì)算機(jī)上拷貝到本地計(jì)算機(jī),或者把本地計(jì)算機(jī)的文件送到遠(yuǎn)程計(jì)算機(jī)上。在Qt中,我們可以使用QNetworkAccessManager和QNetworkReply類來(lái)進(jìn)行FTP程序的編寫(xiě)。但是,對(duì)于較復(fù)雜的FTP操作,Qt還提供了QFtp類。

在QFtp中,所有的操作都對(duì)應(yīng)一個(gè)特定的函數(shù),我們可以稱它們?yōu)槊睢H鏲onnectToHost()連接到效勞器命令,login()登錄命令,get()下載命令,mkdir()新建目錄命令等。?QFtp類以異步方式工作,所有的這些函數(shù)都不是阻塞函數(shù)。也就是說(shuō),如果一個(gè)操作不能立即執(zhí)行,那么這個(gè)函數(shù)就會(huì)直接返回,直到程序控制權(quán)返回Qt事件循環(huán)后才真正執(zhí)行,它們不會(huì)影響界面的顯示。3FTP編程所有的命令都返回一個(gè)int型的編號(hào),使用這個(gè)編號(hào)讓我們可以跟蹤這個(gè)命令,查看其執(zhí)行狀態(tài)。每條命令開(kāi)始執(zhí)行時(shí),都會(huì)發(fā)出commandStarted()信號(hào),該命令執(zhí)行結(jié)束時(shí),會(huì)發(fā)出commandFinished()信號(hào)??梢岳眠@兩個(gè)信號(hào)和命令的編號(hào)來(lái)獲取命令的執(zhí)行狀態(tài)??梢允褂胏urrentCommand()獲取現(xiàn)在執(zhí)行的命令,其返回值與命令對(duì)應(yīng)關(guān)系如以下圖。3FTP編程-例子1?在這個(gè)例子中我們從FTP效勞器上下載一個(gè)文件并顯示出來(lái)。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");//跳轉(zhuǎn)到“qt”目錄下ftp->get("INSTALL");//下載“INSTALL”文件ftp->close();//關(guān)閉連接connect(ftp,SIGNAL(commandStarted(int)),this,SLOT(ftpCommandStarted(int)));//當(dāng)每條命令開(kāi)始執(zhí)行時(shí)發(fā)出相應(yīng)的信號(hào)connect(ftp,SIGNAL(commandFinished(int,bool)),this,SLOT(ftpCommandFinished(int,bool)));//當(dāng)每條命令執(zhí)行結(jié)束時(shí)發(fā)出相應(yīng)的信號(hào)}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("正在關(guān)閉連接…"));}}3FTP編程-例子1?Widget.cpp參考代碼voidWidget::ftpCommandFinished(int,boolerror){if(ftp->currentCommand()==QFtp::ConnectToHost){if(error)ui->label->setText(tr("連接效勞器出現(xiàn)錯(cuò)誤:%1").arg(ftp->errorString()));elseui->label->setText(tr("連接到效勞器成功"));}if(ftp->currentCommand()==QFtp::Login){if(error)ui->label->setText(tr("登錄出現(xiàn)錯(cuò)誤:%1").arg(ftp->errorString()));elseui->label->setText(tr("登錄成功"));}if(ftp->currentCommand()==QFtp::Get){if(error)ui->label->setText(tr("下載出現(xiàn)錯(cuò)誤:%1").arg(ftp->errorString()));else{ui->label->setText(tr("已經(jīng)完成下載"));ui->textBrowser->setText(ftp->readAll());}}elseif(ftp->currentCommand()==QFtp::Close){ui->label->setText(tr("已經(jīng)關(guān)閉連接"));}}3FTP編程-例子2?該例子將例子1程序進(jìn)行擴(kuò)展,使其可以瀏覽并能下載效勞器上的所有文件。實(shí)現(xiàn)在用戶填寫(xiě)完相關(guān)信息后,按下“連接”按鈕,就可以連接到FTP效勞器,并在TreeWidget中顯示效勞器上的所有文件,我們可以按下“下載”按鈕來(lái)下載選中的文件,并使用進(jìn)度條顯示下載進(jìn)度3FTP編程-例子2privateslots:voidon_downloadButton_clicked();voidon_cdToParentButton_clicked();voidon_connectButton_clicked();voidftpCommandFinished(int,bool);voidftpCommandStarted(int);voidupdateDataTransferProgress(qint64,qint64);//更新進(jìn)度條voidaddToList(constQUrlInfo&urlInfo);//將效勞器上的文件添加到TreeWidget中voidprocessItem(QTreeWidgetItem*,int);//雙擊一個(gè)目錄時(shí)顯示其內(nèi)容};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)));//鼠標(biāo)雙擊列表中的目錄時(shí),我們進(jìn)入該目錄}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);//連接到效勞器,默認(rèn)端口號(hào)是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("正在關(guān)閉連接…"));}}3FTP編程-例子2Widget.cpp代碼如下:voidWidget::ftpCommandFinished(int,boolerror){if(ftp->currentCommand()==QFtp::Login){if(error)ui->label->setText(tr("登錄出現(xiàn)錯(cuò)誤:%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)錯(cuò)誤:%1").arg(ftp->errorString()));else{ui->label->setText(tr("已經(jīng)完成下載"));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)){//如果這個(gè)文件是個(gè)目錄,那么翻開(kāi)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();//存儲(chǔ)該路徑是否為目錄的信息

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獲取本機(jī)網(wǎng)絡(luò)信息?如果要獲取自己電腦的IP地址以及其他網(wǎng)絡(luò)信息。會(huì)涉及到網(wǎng)絡(luò)模塊〔QtNetworkModule〕中的QHostInfo,QHostAddress,QNetworkInterface和QNetworkAddressEntry等類?!?〕使用QHostInfo獲取主機(jī)名和IP地址獲取主機(jī)名字:QHostInfo::localHostName()獲取IP地址: QHostInfoinfo=QHostInfo::fromName(localHostName); qDebug()<<”IPAddress:“<<info.addresses();〔2〕通過(guò)QNetworkInterface類來(lái)獲取本機(jī)的IP地址和網(wǎng)絡(luò)接口信息QNetworkInterface類提供了程序所運(yùn)行時(shí)的主機(jī)的IP地址和網(wǎng)絡(luò)接口信息的列表。在每一個(gè)網(wǎng)絡(luò)接口信息中都包含了0個(gè)或多個(gè)IP地址,而每一個(gè)IP地址又包含了和它相關(guān)的子網(wǎng)掩碼和播送地址,它們?nèi)弑环庋b在一個(gè)QNetworkAddressEntry對(duì)象中。網(wǎng)絡(luò)接口信息中也提供了硬件地址信息。4獲取本機(jī)網(wǎng)絡(luò)信息?QList<QNetworkInterface>list=QNetworkInterface::allInterfaces();//獲取所有網(wǎng)絡(luò)接口的列表foreach(QNetworkInterfaceinterface,list)//遍歷每一個(gè)網(wǎng)絡(luò)接口{qDebug()<<"Device:"<<();//設(shè)備名qDebug()<<"HardwareAddress:"<<interface.hardwareAddress();//硬件地址QList<QNetworkAddressEntry>entryList=interface.addressEntries();//獲取IP地址條目列表,每個(gè)條目中包含一個(gè)IP地址,一個(gè)子網(wǎng)掩碼和一個(gè)播送地址foreach(QNetworkAddressEntryentry,entryList)//遍歷每一個(gè)IP地址條目{qDebug()<<"IPAddress:"<<entry.ip().toString();//IP地址qDebug()<<"Netmask:"<<mask().toString();//子網(wǎng)掩碼qDebug()<<"Broadcast:"<<entry.broadcast().toString();//播送地址}}4獲取本機(jī)網(wǎng)絡(luò)信息?常用的獲取IP地址的方法:QStringWidget::getIP()

//獲取ip地址

{

QList<QHostAddress>list=QNetworkInterface::allAddresses();

foreach(QHostAddressaddress,list)

{

if(tocol()==QAbstractSocket::IPv4Protocol)

returnaddress.toString();

}

return0;

}5UDP編程?UDP〔UserDatagramProtocol即用戶數(shù)據(jù)報(bào)協(xié)議〕是一個(gè)輕量級(jí)的,不可靠的,面向數(shù)據(jù)報(bào)的無(wú)連接協(xié)議。騰訊QQ,其聊天時(shí)就是使用UDP協(xié)議進(jìn)行消息發(fā)送的。就像QQ那樣,當(dāng)有很多用戶,發(fā)送的大局部都是短消息,要求能及時(shí)響應(yīng),并且對(duì)平安性要求不是很高的情況下使用UDP協(xié)議。在Qt中提供了QUdpSocket類來(lái)進(jìn)行UDP數(shù)據(jù)報(bào)〔datagrams〕的發(fā)送和接收。這里我們還要了解一個(gè)名詞Socket,也就是常說(shuō)的“套接字”。Socket簡(jiǎn)單地說(shuō),就是一個(gè)IP地址加一個(gè)port端口。因?yàn)槲覀円獋鬏敂?shù)據(jù),就要知道往哪個(gè)機(jī)子上傳送,而IP地址確定了一臺(tái)主機(jī),但是這臺(tái)機(jī)子上可能運(yùn)行著各種各樣的網(wǎng)絡(luò)程序,我們要往哪個(gè)程序中發(fā)送呢?這時(shí)就要使用一個(gè)端口來(lái)指定UDP程序。所以說(shuō),Socket指明了數(shù)據(jù)報(bào)傳輸?shù)穆窂健?UDP編程?例子:編寫(xiě)兩個(gè)程序,一個(gè)用來(lái)發(fā)送數(shù)據(jù)報(bào),可以叫做客戶端;另一個(gè)用來(lái)接收數(shù)據(jù)報(bào),可以叫做效勞器端,它們均應(yīng)用UDP協(xié)議。這樣也就構(gòu)成了所謂的C/S〔客戶端/效勞器〕編程模型??蛻舳说慕缑嫒缫韵聢D:5UDP編程?“開(kāi)始播送”按鈕的單擊事件槽函數(shù):voidWidget::on_pushButton_clicked()

//發(fā)送播送{

QByteArraydatagram=“helloworld!”;

sender->writeDatagram(datagram.data(),datagram.size(),

QHostAddress::Broadcast,45454);}這里我們定義了一個(gè)QByteArray類型的數(shù)據(jù)報(bào)datagram,其內(nèi)容為“helloworld!”。然后使用QUdpSocket類的writeDatagram()函數(shù)來(lái)發(fā)送數(shù)據(jù)報(bào),這個(gè)函數(shù)有四個(gè)參數(shù),分別是數(shù)據(jù)報(bào)的內(nèi)容,數(shù)據(jù)報(bào)的大小,主機(jī)地址和端口號(hào)。對(duì)于數(shù)據(jù)報(bào)的大小,它根據(jù)平臺(tái)的不同而不同,但是這里建議不要超過(guò)512字節(jié)。這里我們使用了播送地址QHostAddress::Broadcast,這樣就可以同時(shí)給網(wǎng)絡(luò)中所有的主機(jī)發(fā)送數(shù)據(jù)報(bào)了。對(duì)于端口號(hào),它是可以隨意指定的,但是一般1024以下的端口號(hào)通常屬于保存端口號(hào),所以我們最好使用大于1024的端口,最大為65535。我們這里使用了45454這個(gè)端口號(hào),一定要注意,在下面要講的效勞器程序中,也要使用相同的端口號(hào)。5UDP編程?效勞器端的界面如以下圖:receiver=newQUdpSocket(this);receiver->bind(45454,QUdpSocket::ShareAddress);connect(receiver,SIGNAL(readyRead()),this,SLOT(processPendingDatagram()));構(gòu)造函數(shù)中將receiver綁定到45454端口,這個(gè)端口就是上面發(fā)送端設(shè)置的端口,二者必須一樣才能保證接收到數(shù)據(jù)報(bào)。我們這里使用了綁定模式QUdpSocket::ShareAddress,它說(shuō)明其他效勞也可以綁定到這個(gè)端口上。當(dāng)receiver發(fā)現(xiàn)有數(shù)據(jù)報(bào)到達(dá)時(shí)就會(huì)發(fā)出readyRead()信號(hào),將其和數(shù)據(jù)報(bào)處理函數(shù)相關(guān)聯(lián)。5UDP編程?voidWidget::processPendingDatagram()//處理等待的數(shù)據(jù)報(bào){while(receiver->hasPendingDatagrams())//擁有等待的數(shù)據(jù)報(bào)

{QByteArraydatagram;//擁于存放接收的數(shù)據(jù)報(bào)

datagram.resize(receiver->pendingDatagramSize());//讓datagram的大小為等待處理的數(shù)據(jù)報(bào)的大小,這樣才能接收到完整的數(shù)據(jù)

receiver->readDatagram(datagram.data(),datagram.size());//接收數(shù)據(jù)報(bào),將其存放到datagram中

ui->label->setText(datagram);//將數(shù)據(jù)報(bào)內(nèi)容顯示出來(lái)

}}5UDP編程?先運(yùn)行效勞器端程序,再運(yùn)行客戶端程序。然后點(diǎn)擊其上的“發(fā)送播送”按鈕,這時(shí)會(huì)顯示數(shù)據(jù)報(bào)的內(nèi)容??梢钥吹?,UDP的應(yīng)用是很簡(jiǎn)單的。我們只需要在發(fā)送端執(zhí)行writeDatagram()函數(shù)進(jìn)行數(shù)據(jù)報(bào)的發(fā)送,然后在接收端綁定端口,并關(guān)聯(lián)readyRead()信號(hào)和數(shù)據(jù)報(bào)處理函數(shù)即可。改程序運(yùn)行效果如以下圖: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. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論