1. 程式人生 > 其它 >[原譯]C#編寫FTP客戶端軟體

[原譯]C#編寫FTP客戶端軟體

[原譯]C#編寫FTP客戶端軟體

1 介紹

我知道。網上有很多現成的FTP軟體。但是。我們也想要了解FTP的一些底層機構,因此。 這個開源的專案在你學習FTP知識的時候也許對你有些幫組。程式的介面看起來像FileZilla,FileZilla雖然流行但是有些bug,當我開啟我部落格的時候總是有問題。我需要通過FTP連線我的伺服器。傳送檔案,下載檔案等等。因為。我決定寫我自己的軟體來處理所有的情況。FileZilla足夠好。但它不是我的。

2 背景

看看我們已經知道的。我們知道FTP是一個標準的基於TCP網路協議。用於從一個主機向另一個主機傳輸檔案。它是一個C/S架構。

圖2

FTP程式曾經是基於命令列的。我們仍沿可以通過cmd.exe連線FTP伺服器。因為FTP的確可以通過命令來操作。舉個例子。我們可以在命令列使用“stor”命令來發送檔案。為了完成這些請求。FTP伺服器需要一直執行等待即將到來的客戶端請求。我們可以從來自維基百科的解釋更好的理解FTP:

客戶端計算機可以通過伺服器的21埠和伺服器通訊。叫做控制連線。它在一次會話期間保持開放。第一次連線的時候。叫做資料連線,伺服器可以對客戶端開啟20埠(主動模式),建立一條資料通路,連線上客戶端傳輸資料。或者客戶端開啟一個隨機的埠(被動模式),去連線伺服器,來傳輸資料。控制連線使用一個類似Telnet的協議,被用作客戶端和伺服器會話管理(命令,標識,密碼)。。比如。"RETRfilename" 會從伺服器端下載檔案。

圖三

一個完整的FTP檔案傳輸需要建立兩種型別的連線,一種為檔案傳輸下命令,稱為控制連線,另一種實現真正的檔案傳輸,稱為資料連線。

伺服器 通過三位ASCII的數字狀態碼,可能包含可選的描述資訊,在控制連線上做出迴應。比如。“200”或者是“200 OK”,表示上一條命令成功了。數字代表編號,描述資訊給出了一些說明(比如“OK”),或者可能是一些需要的引數(比如需要帳號來儲存檔案),那麼我們需要怎麼做呢。很明顯。傳送命令,接收“OK”迴應,傳送資料。接收資料。完了。但是首先需要伺服器已經準備好了。FTP伺服器可以在主動和被動兩種模式下執行。主動模式是基於伺服器的連線而被動模式是基友客戶端的連線。繼續看。

在主動連線中,客戶端把自己的ip和埠傳送給伺服器。然後伺服器嘗試連線到客戶端,但是可能會因為防火牆的原因而被拒絕。我們在windows上都會使用反病毒/自帶防火牆。是吧。那麼我們來看看被動模式

在被動連線中。伺服器通過一個“PASV”命令把自己的ip和埠傳送給客戶端。然後客戶端通過該IP嘗試連線伺服器。對於傳送檔案非常有用。當我們傳送檔案的時候。優先使用“PASV”模式,如你們所說。大多數協議。像FTP/HTTP 使用ASCII編碼,因為全球可用。因此我們會使用這種編碼。你可以從下面得到FTP的命令列表

主動和被動都是對於伺服器端來說的

3 使用程式碼

現在我們已經為編寫軟體做好準備了。我們寫些有用的程式碼吧。:)首先。我們“開啟檔案對話方塊”,整合到我們的窗體裡。

3.1 資源管理器元件

我們需要一個資源管理器元件在軟體介面可以看到我們所有的檔案。這樣我們才可以選擇哪些檔案來發送到FTP伺服器,新建一個Windows窗體控制元件庫(下載包中提供了)

圖四

最後看起來樣子是上面這樣。先新增一個TreeView,一些按鈕,和一個搜尋功能

TreeView.Nodes.Clear();

TreeNode nodeD = new TreeNode();

nodeD.Tag = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

nodeD.Text = "Desktop";

nodeD.ImageIndex = 10;

nodeD.SelectedImageIndex = 10;

TreeView.Nodes.Add(nodeD);

就像上面程式碼展示的那樣。我們需要新增地一個主節點。我的文件。我的電腦等等。然後獲得子目錄。

string[] dirList;
dirList = Directory.GetDirectories(parentNode.Tag.ToString());
Array.Sort(dirList);
if (dirList.Length == parentNode.Nodes.Count)
    return;
for (int i = 0; i < dirList.Length; i++)
{
    node = new TreeNode();
    node.Tag = dirList[i]; 
    node.Text = dirList[i].Substring(dirList[i].LastIndexOf(@"\") + 1);
    node.ImageIndex = 1;
    parentNode.Nodes.Add(node);
}

可以從下載包裡看到完整的程式碼。我們還應該處理滑鼠單擊事件。

現在我們有了一個資源管理器。還有FTP和VS所需要的所有資訊。

首先,我們連線伺服器。我們應該怎麼做呢?

FTPSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
AppendText(rchLog,"Status : Resolving IP Address\n",Color.Red);
remoteAddress = Dns.GetHostEntry(Server).AddressList[0];
AppendText(rchLog, "Status : IP Address Found ->" + remoteAddress.ToString() + "\n", Color.Red);
addrEndPoint = new IPEndPoint(remoteAddress, Port);
AppendText(rchLog,"Status : EndPoint Found ->" + addrEndPoint.ToString() + "\n", Color.Red);
FTPSocket.Connect(addrEndPoint);
是的。我們需要一個socket連線到伺服器 ,然後傳送命令
AppendText(rchLog, "Command : " + msg + "\n", Color.Blue);
Byte[] CommandBytes = Encoding.ASCII.GetBytes((msg + "\r\n").ToCharArray());
FTPSocket.Send(CommandBytes, CommandBytes.Length, 0);
//read Response
ReadResponse();

我們傳送命令到伺服器。伺服器以他自己的語言來響應。我們需要理解他。響應包括3位數字和一些解釋。

private string SplitResponse()
{
    try
    {
        while (true)
        {
            Bytes = FTPSocket.Receive(Buffer, Buffer.Length, 0); //Number Of Bytes (Count)
            StatusMessage += Encoding.ASCII.GetString(Buffer, 0, Bytes); //Convert to String
            if (Bytes < Buffer.Length)  //End Of Response
                break;
        }
        string[] msg = StatusMessage.Split('\n');
        if (StatusMessage.Length > 2)
            StatusMessage = msg[msg.Length - 2];  //Remove Last \n
        else
            StatusMessage = msg[0];
        if (!StatusMessage.Substring(3, 1).Equals(" "))
            return SplitResponse();
        for (int i = 0; i < msg.Length - 1; i++)
            AppendText(rchLog, "Response : " + msg[i] + "\n", Color.Green);
        return StatusMessage;
    }
    catch(Exception ex)
    {
        AppendText(rchLog, "Status : ERROR. " +ex.Message+ "\n", Color.Red);
        FTPSocket.Close();
        return "";
    }
}

完了。現在我們可以下載,上傳,重新命名。或者刪除了。

4 FTP命令列表

命令 描述
ABOR 中斷一個活動的檔案傳輸
ACCT 系統帳號資訊
ADAT 認證/安全資料
ALLO 分配空間來接收檔案
APPE 新增檔案到伺服器
AUTH 認證/安全機制
CCC 清除命令通道
CDUP 轉到父目錄
CONF 機密性保護命令
CWD 改變伺服器上的工作目錄
DELE 刪除伺服器上的指定檔案
ENC 機密保護通道
EPRT 指定一個伺服器應該連線的擴充套件地址和埠
EPSV 進入擴充套件的被動模式
FEAT 得到伺服器提供的功能列表
HELP 返回指定命令資訊
LANG 返回語言資訊
LIST 如果是檔名列出檔案資訊,如果是目錄則列出檔案列表
LPRT 指定一個伺服器應該連線的長地址和埠
LPSV 進入長被動模式
MDTM 返回檔案最近修改時間
MIC 完整的保護命令
MKD 建立目錄
MLSD 列出指定目錄的內容
MLST 在命令列上列出物件的精確資訊
MODE 傳輸模式(S=流模式,B=塊模式,C=壓縮模式)
NLST 列出指定目錄內容
NOOP 無動作,(虛包,來自常連線中)
OPTS 選擇一個功能的選項
PASS 驗證密碼
PASV 進入被動模式
PBSZ 保護緩衝區大小
PORT 指定伺服器應該連線的地址和埠
PROT 資料通道保護級別
PWD 顯示當前工作目錄
QUIT 從FTP伺服器上退出登入
REIN 重新初始化登入狀態連線
REST 由指定點重啟檔案傳遞
RETR 傳遞檔案副本
RMD 在伺服器上刪除指定目錄
RNFR 從舊名稱重新命名
RNTO 到新名稱
SITE 向遠端伺服器傳送指定命令
SIZE 返回檔案大小
SMNT 掛載指定檔案結構
STAT 返回當前狀態
STOR 儲存(複製)檔案到伺服器上
STOU 儲存檔案到伺服器指定檔案上
STRU 設定結構(F=檔案,R=記錄,P=頁面)
SYST 返回伺服器使用的作業系統
TYPE 傳輸模式(A=ASCII,E=EBCDIC,I=binary)
USER 驗證使用者
XCUP 跳到當前工作路徑的父目錄
XMKD 新建目錄
XPWD 輸出當前工作目錄
XRMD 刪除目錄

5 返回碼列表

  • 2xx –返回成功
  • 4xx or 5xx – 返回失敗
  • 1xx or 3xx – 錯誤或不完整的回覆

第二位定義了錯誤的型別

  • x0z – 語法 – 有語法錯誤.
  • x1z – 資訊 – 請求提供資訊
  • x2z – 連線 – 說明控制或資料連線有問題
  • x3z – 賬戶認證 – 登入或者是賬戶認證有問題.
  • x4z – 未定義
  • x5z – 檔案系統 – 可能是伺服器檔案系統有問題。

Demo 下載

C#編寫FTP客戶端

6 許可

本文包括原始碼和檔案在CPOL下授權。