解析 Qt 網絡之FTP 網絡學習基礎
Qt 網絡之FTP 網絡學習基礎是本文要介紹的內容,先來可能內容。FTP即File Transfer Protocol,也就是文件傳輸協議。FTP的主要作用,就是讓用戶連接上一個遠程計算機,查看遠程計算機有哪些文件,然后把文件從遠程計算機上拷貝到本地計算機,或者把本地計算機的文件送到遠程計算機上。
在Qt中,我們可以使用上一節講述的QNetworkAccessManager和QNetworkReply類來進行FTP 程序的編寫,因為它們用起來很簡單。但是,對于較復雜的FTP操作,Qt還提供了QFtp類,利用這個類,我們很容易寫出一個FTP客戶端程序。下面我們先在幫助中查看這個類。
在QFtp中,所有的操作都對應一個特定的函數,我們可以稱它們為命令。如connectToHost()連接到服務器命令,login()登錄命令,get()下載命令,mkdir()新建目錄命令等。因為QFtp類以異步方式工作,所以所有的這些函數都不是阻塞函數。也就是說,如果一個操作不能立即執行,那么這個函數就會直接返回,直到程序控制權返回Qt事件循環后才真正執行,它們不會影響界面的顯示。
所有的命令都返回一個int 型的編號,使用這個編號讓我們可以跟蹤這個命令,查看其執行狀態。當每條命令開始執行時,都會發出commandStarted()信號,當該命令執行結束時,會發出commandFinished()信號。我們可以利用這兩個信號和命令的編號來獲取命令的執行狀態。當然,我們不想執行每條命令都要記下它的編號,所以我們也可以使用currentCommand()來獲取現在執行的命令,其返回值與命令的對應關系如下圖。
下面我們先看一個簡單的FTP客戶端的例子,然后對它進行擴展。
在這個例子中我們從FTP服務器上下載一個文件并顯示出來。
1、我們新建Qt4 Gui QApplication 。
工程名為“myFtp”,然后選中QtNetwork模塊,最后Base class選擇QWidget 。
2、修改widget.ui文件。
在其中添加一個Text Browser 和一個 Label,效果如下。
3、在main.cpp中進行修改。
為了在程序中可以使用中文,我們在main.cpp中添加頭文件#include <QTextCodec>
并在main()函數中添加代碼:QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
#p#
4、在widget.h中進行修改。
先添加頭文件:#include <QFtp>
再在private中定義對象:QFtp *ftp;
添加私有槽函數:
- private slots:
- void ftpCommandStarted(int);
- void ftpCommandFinished(int,bool);
5、在widget.cpp中進行更改。
(1)在構造函數中添加代碼:
- ftp = new QFtp(this);
- ftp->connectToHost(“ftp.qt.nokia.com”); //連接到服務器
- ftp->login(); //登錄
- ftp->cd(“qt”); //跳轉到“qt”目錄下
- ftp->get(“INSTALL”); //下載“INSTALL”文件
- ftp->close(); //關閉連接
- connect(ftp,SIGNAL(commandStarted(int)),
- this,SLOT(ftpCommandStarted(int)));
- //當每條命令開始執行時發出相應的信號
- connect(ftp,SIGNAL(commandFinished(int,bool)),
- this,SLOT(ftpCommandFinished(int,bool)));
- //當每條命令執行結束時發出相應的信號
我們在構造函數里執行了幾個FTP的操作,登錄站點,并下載了一個文件。然后我們又關聯了兩個信號和槽,用來跟蹤命令的執行情況。
(2)實現槽函數:
- void Widget::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(“正在下載…”));
- }
- else if (ftp->currentCommand() == QFtp::Close){
- ui->label->setText(tr(“正在關閉連接…”));
- }
- }
每當命令執行時,都會執行ftpCommandStarted()函數,它有一個參數int id,這個id就是調用命令時返回的id,如int loginID = ftp->login(); 這時,我們就可以用if(id == loginID)來判斷執行的是否是login()函數。但是,我們不想為每個命令都設置一個變量來存儲其返回值,所以,我們這里使用了ftp->currentCommand() ,它也能獲取當前執行的命令的類型。在這個函數里我們讓開始不同的命令時顯示不同的狀態信息。
- void Widget::ftpCommandFinished(int,bool error)
- {
- if(ftp->currentCommand() == QFtp::ConnectToHost){
- if(error) ui->label->setText(tr(“連接服務器出現錯誤:%1″).arg(ftp->errorString()));
- else ui->label->setText(tr(“連接到服務器成功”));
- }
- if (ftp->currentCommand() == QFtp::Login){
- if(error) ui->label->setText(tr(“登錄出現錯誤:%1″).arg(ftp->errorString()));
- else ui->label->setText(tr(“登錄成功”));
- }
- if (ftp->currentCommand() == QFtp::Get){
- if(error) ui->label->setText(tr(“下載出現錯誤:%1″).arg(ftp->errorString()));
- else {
- ui->label->setText(tr(“已經完成下載”));
- ui->textBrowser->setText(ftp->readAll());
- }
- }
- else if (ftp->currentCommand() == QFtp::Close){
- ui->label->setText(tr(“已經關閉連接”));
- }
- }
這個函數與ftpCommandStarted()函數相似,但是,它是在一個命令執行結束時執行的。它有兩個參數,第一個int id,就是調用命令時返回的編號,我們在上面已經講過了。第二個是bool error,它標志現在執行的命令是否出現了錯誤。如果出現了錯誤,那么error 為true ,否則為false。我們可以利用它來輸出錯誤信息。在這個函數中,我們在完成一條命令時顯示不同的狀態信息,并顯示可能的出錯信息。在if (ftp->currentCommand() == QFtp::Get) 中,也就是已經完成下載時,我們讓textBrowser顯示下載的信息。
#p#
6、運行程序,效果如下。
登錄狀態。
下載完成后。
7.出錯演示。
下面我們演示一下出錯時的情況。
將構造函數中的代碼ftp->login();改為ftp->login(“tom”,”123456″);
這時我們再運行程序:
可以看到,它輸出了錯誤信息,指明了錯誤的指令和出錯的內容。其實我們設置的這個錯誤,也是想告訴大家,在FTP中如果沒有設置用戶名和密碼,那么默認的用戶名應該是anonymous,這時密碼可以任意填寫,而使用其他用戶名是會出錯的。
在下一節中,我們將會對這個程序進行擴展,讓它可以瀏覽服務器上的所有文件,并進行下載。
本文來自:www.yafeilinux.com
小結:Qt 網絡之FTP 網絡學習基礎的內容介紹完了,更多內容,請參考編輯推薦。給大家推薦與此文相關的幾篇文章,供您參考。
http://mobile.51cto.com/symbian-268176.htm qt網絡
http://mobile.51cto.com/symbian-268170.htm http 編程
http://mobile.51cto.com/symbian-268167_1.htm 獲取網絡地址