首先該DEMO在StreamCoder上面做的改動,期間導致StreamCoderDEMO經常出現問題,導致大家運行的時候,頻頻出現問題,表示道歉。
以下是測試的結果,從服務器下載傳輸了一個3G左右的文件(Win7.iso)。傳輸后用Hash工具做了個測試,是一樣的。后面貼出了兩個文件的貼圖。
下面是客戶端接受到文件的hash截圖
下面是服務端源文件的hash截圖
協議和功能
該DEMO由客戶端請求服務端位與Files下面的文件,第一次請求文件信息(文件大小),請求到文件后,請求下載文件數據,收到后重復繼續請求下載下一塊文件數據,直到所有數據完成。
該DEMO的Stream文件頭寫入了該結構體信息。
TFileHead = record
Flag: Word; //固定$A1標記
cmd: Word; // 1, 請求文件數據, 2: 文件數據, 10: 請求文件信息, 11: 文件信息數據
FileName: string[255]; //文件名
Position: Int64; //文件位置<請求文件數據時指定讀取文件數據的位置>
Size: Int64; //數據大小<請求文件數據時表示請求的數據大小;返回文件數據(2)時,表示數據的大小。
crc: Cardinal; //暫時沒有試用
cmd_result:Integer; // 0:成功, 1:文件找不到, 2:出現了異常, 3:錯誤的請求參數
end;
由於下載數據的位置和大小可以由請求中進行指定,所以可以進行斷點續傳,這是我平常用到的協議。
部分代碼講解
客戶端由一個IocpFileTrans類完成主要的功能。
改按鈕代表請求下載服務端Files\demoFile.jpg文件。
procedure TfrmMain.btnGetFileClick(Sender: TObject); begin if not FiocpCoderTcpClient.isActive then begin uiLogger.logMessage('please do connect'); exit; end; FFileAsyncTrans.requestFileINfo(edtFileID.Text); end;
請求有回應后(onRecvObject),進行文件數據的請求
接收到數據后(onRecvObject),寫入數據后,繼續請求下一塊數據,所有數據(Postion = size)完成,關閉文件,完成下載。
服務端有MyClientContext類處理客戶端的請求和返回數據的工作
請求文件信息命令, 返回文件信息,(文件大小:lvResult.size)
請求文件數據,返回讀取的文件大小(lvResult.Size), 和文件數據lvFileData
最后將文件頭信息和文件數據合並到Stream中,用writeObject方法返回給客戶端。
上面講述了客戶端和服務端文件處理的流程部分的代碼。該DEMO只是一個演示,希望能加深大家對diocp的理解。
DEMO路徑存放 samples\iocp-coder\streamCoder
注意:請求的文件必須存在輸出路徑的Files目錄下面,
客戶端請求的文件,只需要Files目錄下面對應的文件名