首先该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目录下面对应的文件名