ESFramework Demo -- 簡單的網絡硬盤Demo

  FTP服務器最核心的功能就是提供文件的上傳、下載服務。在ESFramework Demo -- 文件傳送Demo(附源碼)一文中,我們演示瞭如何在客戶端與客戶端之間相互傳送文件,現在我們就實現一個簡單的FTP服務器,以演示如何在客戶端與服務器之間傳送文件。在閱讀本文之前,請務必先掌握ESFramework 開發手冊(03) -- 文件(夾)傳送 一文中介紹的文件傳送的流程及相關的API的用法。

本Demo主要演示以下功能:

(1)客戶端瀏覽服務器默認目錄下的所有文件。

(2)客戶端上傳文件到服務器的默認目錄下。

(3)客戶端可以下載服務器默認目錄下任何一個文件。

一.定義信息類型
根據上面提到的功能需求,我們需要定義相應的信息類型:

複製代碼
public static class FtpInformationTypes
{
/// <summary>
/// 獲取所有文件名。C->S
/// </summary>
public const int GetAllFileNames = 0;
/// <summary>
/// 請求下載文件。C->S
/// </summary>
public const int DownloadFile = 1;
}
複製代碼
上傳文件就不用定義額外的信息類型了,可以直接使用IFileOutter的請求發送文件方法就可以了。

二.服務端
服務端將文件目錄設定在運行目錄下的"FileFold"文件夾,所有上傳的文件都將被保存到這個目錄,所有要下載的文件也來自這個目錄。

  服務端的CustomizeHandler類實現了自定義信息處理器接口ICustomizeHandler,當收到來自客戶端的FtpInformationTypes.GetAllFileNames同步調用時,就將FileFold目錄下的所有文件列表返回給客戶端。當收到請求下載文件的信息時,就調用IFileController.BeginSendFile方法將指定的文件發給客戶端。

  當客戶端要上傳文件時,會直接調用IFileOutter的BeginSendFile,此時,服務端將觸發IFileController的FileRequestReceived事件。所以,服務端需要預定並處理這個事件: 

複製代碼
void fileController_FileRequestReceived(string fileID, string senderID, string fileName, ulong fileLength, ESPlus.FileTransceiver.ResumedProjectItem resumedProjectItem, string comment)
{
int index = fileName.LastIndexOf('\');
string filePath = string.Format(@"{0}FileFold{1}", AppDomain.CurrentDomain.BaseDirectory, fileName.Substring(index +1));
this.fileController.BeginReceiveFile(fileID, filePath);
}
複製代碼
服務端將保存文件的路徑設定在FileFold目錄下,然後調用IFileController.BeginReceiveFile方法開始接收文件。當然,這裏的處理做了很多簡化,比如沒有判斷磁盤空間是否足夠、是否有同名文件等等。

三.客戶端
客戶端登錄成功後,進入主界面。主界面初始化時,將向服務器發送FtpInformationTypes.GetAllFileNames同步調用,然後將返回的文件列表顯示在ListView中。

  雙擊ListView中的某個文件時,就向服務器發送FtpInformationTypes.DownloadFile信息。就像上面描述的一樣,服務端就會調用IFileController.BeginSendFile方法發送指定的文件,然後,客戶端也會觸發IFileOutter.FileRequestReceived事件,處理這個事件時,我們讓用戶選擇要存儲的路徑。 

複製代碼
void fileOutter_FileRequestReceived(string projectID, string senderID, string fileName, ulong totalSize, ResumedProjectItem resumedFileItem, string comment)
{
if (this.InvokeRequired)
{
this.Invoke(new CbReadyToAcceptFileAsyn(this.fileOutter_FileRequestReceived), projectID, senderID, fileName, totalSize, resumedFileItem, comment);
}
else
{
string savePath = ESBasic.Helpers.FileHelper.GetPathToSave("保存", fileName, null);
if (string.IsNullOrEmpty(savePath))
{
this.fileOutter.RejectFile(projectID);
}
else
{
this.fileOutter.BeginReceiveFile(projectID, savePath);
}
}
}
複製代碼
如果用戶取消了保存路徑的選擇,表示放棄下載文件,這樣就調用IFileOutter.RejectFile來進行取消操作。
當客戶端點擊上傳按鈕時,就直接調用IFileOutter.BeginSendFile來準備上傳文件。

複製代碼
private void toolStripButton_upLoad_Click(object sender, EventArgs e)
{
string filePath = ESBasic.Helpers.FileHelper.GetFileToOpen("打開");
if (filePath == null)
{
return;
}
string fileID;
SendingFileParas sendingFileParas = new SendingFileParas(2048, 0);//文件數據包大小,可以根據網絡狀況設定,局網內可以設爲204800,傳輸速度可以達到30M/s以上;公網建議設定爲2048或4096或8192
this.fileOutter.BeginSendFile(NetServer.SystemUserID, filePath, null, sendingFileParas, out fileID);
}
複製代碼
這將引發服務端IFileController的FileRequestReceived事件觸發,然後,服務端會調用IFileController.BeginReceiveFile方法,從而啓動文件的正式傳遞。

  下圖是客戶端正在進行上傳下載文件時的截圖:       

   本文是一個最簡單的演示文件上傳下載功能的demo,非常的粗糙,僅僅用於示範如何使用ESPlus提供的文件傳送功能在服務端和客戶端之間傳遞文件。若要正式開發一個文件服務器系統,本文只能算是一個簡陋的起點,還有很多複雜的事情要做,那已經超出了本文的內容,但你若有任何想法,歡迎與我們討論。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章