天天看點

[Qt教程] 第33篇 網絡(三)FTP(一) [Qt教程] 第33篇 網絡(三)FTP(一)

<a target="_blank" href="http://bbs.qter.org/forum.php?mod=viewthread&amp;tid=602">樓主</a>

[Qt教程] 第33篇 網絡(三)FTP(一) [Qt教程] 第33篇 網絡(三)FTP(一)

 發表于 2013-9-4 14:52:46 | 檢視:

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用戶端程式。下面我們先在幫助中檢視這個類。

[Qt教程] 第33篇 網絡(三)FTP(一) [Qt教程] 第33篇 網絡(三)FTP(一)

在qftp中,所有的操作都對應一個特定的函數,我們可以稱它們為指令。如connecttohost()連接配接到伺服器指令,login()登入指令,get()下載下傳指令,mkdir()建立目錄指令等。因為qftp類以異步方式工作,是以所有的這些函數都不是阻塞函數。也就是說,如果一個操作不能立即執行,那麼這個函數就會直接傳回,直到程式控制權傳回qt事件循環後才真正執行,它們不會影響界面的顯示。

所有的指令都傳回一個int 型的編号,使用這個編号讓我們可以跟蹤這個指令,檢視其執行狀态。當每條指令開始執行時,都會發出commandstarted()信号,當該指令執行結束時,會發出commandfinished()信号。我們可以利用這兩個信号和指令的編号來擷取指令的執行狀态。當然,如果不想執行每條指令都要記下它的編号,也可以使用currentcommand()來擷取現在執行的指令,其傳回值與指令的對應關系如下圖。

[Qt教程] 第33篇 網絡(三)FTP(一) [Qt教程] 第33篇 網絡(三)FTP(一)

下面我們先看一個簡單的ftp用戶端的例子,然後對它進行擴充。在這個例子中我們從ftp伺服器上下載下傳一個檔案并顯示出來。

1.我們建立qt gui應用。

項目名次為“myftp”,基類選擇qwidget,類名保持widget即可。完成後打開muftp.pro檔案,在上面添加一行:qt +=

network,然後儲存該檔案。

2.修改widget.ui檔案。

在其中添加一個textbrowser 和一個 label,效果如下。

[Qt教程] 第33篇 網絡(三)FTP(一) [Qt教程] 第33篇 網絡(三)FTP(一)

3.在main.cpp中進行修改。

為了在程式中可以使用中文,我們在main.cpp中添加頭檔案#include &lt;qtextcodec&gt;

并在main()函數中添加代碼:

qtextcodec::setcodecfortr(qtextcodec::codecforlocale());

4.在widget.h中進行修改。

先添加頭檔案:#include &lt;qftp&gt;

再在private中定義對象:qftp *ftp;

添加私有槽函數:

private slots:

    void ftpcommandstarted(int);

void ftpcommandfinished(int,bool);

5.在widget.cpp中進行更改。

(1)在構造函數中添加代碼:

ftp = new qftp(this);

ftp-&gt;connecttohost("ftp.qt-project.org"); //連接配接到伺服器

ftp-&gt;login();   //登入

ftp-&gt;cd("qt/source");   //跳轉到“qt”目錄下的source目錄中

ftp-&gt;get("install");  //下載下傳“install”檔案

ftp-&gt;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-&gt;currentcommand() == qftp::connecttohost){

       ui-&gt;label-&gt;settext(tr("正在連接配接到伺服器..."));

    }

    if (ftp-&gt;currentcommand() == qftp::login){

       ui-&gt;label-&gt;settext(tr("正在登入..."));

    if (ftp-&gt;currentcommand() == qftp::get){

       ui-&gt;label-&gt;settext(tr("正在下載下傳..."));

    else if (ftp-&gt;currentcommand() == qftp::close){

       ui-&gt;label-&gt;settext(tr("正在關閉連接配接..."));

}

每當指令執行時,都會執行ftpcommandstarted()函數,它有一個參數int id,這個id就是調用指令時傳回的id,如int

loginid= ftp-&gt;login(); 這時,我們就可以用if(id == loginid)來判斷執行的是否是login()函數。但是,我們不想為每個指令都設定一個變量來存儲其傳回值,是以,我們這裡使用了ftp-&gt;currentcommand() ,它也能擷取目前執行的指令的類型。在這個函數裡我們讓開始不同的指令時顯示不同的狀态資訊。

void widget::ftpcommandfinished(int,bool error)

       if(error)

           ui-&gt;label-&gt;settext(tr("連接配接伺服器出現錯誤:%1")

                               .arg(ftp-&gt;errorstring()));

       else ui-&gt;label-&gt;settext(tr("連接配接到伺服器成功"));

           ui-&gt;label-&gt;settext(tr("登入出現錯誤:%1")

       else ui-&gt;label-&gt;settext(tr("登入成功"));

           ui-&gt;label-&gt;settext(tr("下載下傳出現錯誤:%1")

       else {

           ui-&gt;label-&gt;settext(tr("已經完成下載下傳"));

           ui-&gt;textbrowser-&gt;settext(ftp-&gt;readall());

       }

       ui-&gt;label-&gt;settext(tr("已經關閉連接配接"));

這個函數與ftpcommandstarted()函數相似,但是,它是在一個指令執行結束時執行的。它有兩個參數,第一個intid,就是調用指令時傳回的編号,我們在上面已經講過了。第二個是bool

error,它标志現在執行的指令是否出現了錯誤。如果出現了錯誤,那麼error 為true ,否則為false。我們可以利用它來輸出錯誤資訊。在這個函數中,我們在完成一條指令時顯示不同的狀态資訊,并顯示可能的出錯資訊。在if

(ftp-&gt;currentcommand() == qftp::get) 中,也就是已經完成下載下傳時,我們讓textbrowser顯示下載下傳的資訊。

6.運作程式,效果如下。

[Qt教程] 第33篇 網絡(三)FTP(一) [Qt教程] 第33篇 網絡(三)FTP(一)

7.出錯示範。

下面我們示範一下出錯時的情況。

将構造函數中的代碼ftp-&gt;login();改為ftp-&gt;login("tom","123456");

這時我們再運作程式:

[Qt教程] 第33篇 網絡(三)FTP(一) [Qt教程] 第33篇 網絡(三)FTP(一)

可以看到,它輸出了錯誤資訊,指明了錯誤的指令和出錯的内容。其實我們設定的這個錯誤,也是想告訴大家,在ftp中如果沒有設定使用者名和密碼,那麼預設的使用者名應該是anonymous,這時密碼可以任意填寫,而使用其他使用者名是會出錯的。

結語

     在下一節中,我們将會對這個程式進行擴充,讓它可以浏覽伺服器上的所有檔案,并進行下載下傳。

涉及的源碼下載下傳: 

[Qt教程] 第33篇 網絡(三)FTP(一) [Qt教程] 第33篇 網絡(三)FTP(一)

kb, 下載下傳次數: 1) 

繼續閱讀