[Qt教程] 第33篇 网络(三)FTP(一)
生活随笔
收集整理的這篇文章主要介紹了
[Qt教程] 第33篇 网络(三)FTP(一)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
[Qt教程]?第33篇 網絡(三)FTP(一)
??|?查看: 392|?回復: 8| FTP(一) 版權聲明 該文章原創于作者yafeilinux,轉載請注明出處! 導語 上一節我們講述了HTTP的編程,這一節講述與其及其相似的FTP的編程。FTP即FileTransfer Protocol,也就是文件傳輸協議。FTP的主要作用,就是讓用戶連接上一個遠程計算機,查看遠程計算機有哪些文件,然后把文件從遠程計算機上拷貝到本地計算機,或者把本地計算機的文件送到遠程計算機上。 環境:Windows Xp + Qt 4.8.5+QtCreator 2.8.0 目錄 一、簡介 二、實現簡單的文件下載 正文 一、簡介 在Qt中,我們可以使用上一節講述的QNetworkAccessManager和QNetworkReply類來進行FTP 程序的編寫,因為它們用起來很簡單。但是,對于較復雜的FTP操作,Qt還提供了QFtp類,利用這個類,我們很容易寫出一個FTP客戶端程序。下面我們先在幫助中查看這個類。 在QFtp中,所有的操作都對應一個特定的函數,我們可以稱它們為命令。如connectToHost()連接到服務器命令,login()登錄命令,get()下載命令,mkdir()新建目錄命令等。因為QFtp類以異步方式工作,所以所有的這些函數都不是阻塞函數。也就是說,如果一個操作不能立即執行,那么這個函數就會直接返回,直到程序控制權返回Qt事件循環后才真正執行,它們不會影響界面的顯示。 所有的命令都返回一個int 型的編號,使用這個編號讓我們可以跟蹤這個命令,查看其執行狀態。當每條命令開始執行時,都會發出commandStarted()信號,當該命令執行結束時,會發出commandFinished()信號。我們可以利用這兩個信號和命令的編號來獲取命令的執行狀態。當然,如果不想執行每條命令都要記下它的編號,也可以使用currentCommand()來獲取現在執行的命令,其返回值與命令的對應關系如下圖。 二、實現簡單的文件下載 下面我們先看一個簡單的FTP客戶端的例子,然后對它進行擴展。在這個例子中我們從FTP服務器上下載一個文件并顯示出來。 1.我們新建Qt Gui應用。 項目名次為“myFtp”,基類選擇QWidget,類名保持Widget即可。完成后打開muFtp.pro文件,在上面添加一行:QT?+= network,然后保存該文件。 2.修改widget.ui文件。 在其中添加一個TextBrowser?和一個?Label,效果如下。 3.在main.cpp中進行修改。 為了在程序中可以使用中文,我們在main.cpp中添加頭文件#include?<QTextCodec> 并在main()函數中添加代碼: QTextCodec::setCodecForTr(QTextCodec::codecForLocale()); 4.在widget.h中進行修改。 先添加頭文件:#include?<QFtp> 再在private中定義對象:QFtp?*ftp; 添加私有槽函數: private?slots: ? ??void?ftpCommandStarted(int); void ftpCommandFinished(int,bool); 5.在widget.cpp中進行更改。 (1)在構造函數中添加代碼: (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()函數相似,但是,它是在一個命令執行結束時執行的。它有兩個參數,第一個intid,就是調用命令時返回的編號,我們在上面已經講過了。第二個是bool error,它標志現在執行的命令是否出現了錯誤。如果出現了錯誤,那么error?為true?,否則為false。我們可以利用它來輸出錯誤信息。在這個函數中,我們在完成一條命令時顯示不同的狀態信息,并顯示可能的出錯信息。在if (ftp->currentCommand() == QFtp::Get)?中,也就是已經完成下載時,我們讓textBrowser顯示下載的信息。 6.運行程序,效果如下。 7.出錯演示。 下面我們演示一下出錯時的情況。 將構造函數中的代碼ftp->login();改為ftp->login("tom","123456"); 這時我們再運行程序: 可以看到,它輸出了錯誤信息,指明了錯誤的指令和出錯的內容。其實我們設置的這個錯誤,也是想告訴大家,在FTP中如果沒有設置用戶名和密碼,那么默認的用戶名應該是anonymous,這時密碼可以任意填寫,而使用其他用戶名是會出錯的。 結語 在下一節中,我們將會對這個程序進行擴展,讓它可以瀏覽服務器上的所有文件,并進行下載。 涉及的源碼下載:??myFtp1.rar?? |
總結
以上是生活随笔為你收集整理的[Qt教程] 第33篇 网络(三)FTP(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Qt教程] 第32篇 网络(二)HTT
- 下一篇: [Qt教程] 第34篇 网络(四)FTP