你先看看FTP协议。
1.按照标准FTP协议,不需要另外定义结构。
2.如果不定结构,也就不再需要拆分文件。
如果是拆分文件,无疑就是将文件一块块的分开放到结构里面发。
用流,API都行。
type
//数据类型 字符串 下载文件 上传文件 记录
TDataType = (dtString, dtGetFile, dtUpFile, dtRecord);
//发送数据记录
TSendData = packed record
FDataType: TDataType; // 数据类型
FSockFlage: Integer; // Server/Client Flage
FDataSize: Integer; // 数据大小
CmdStr: array[1..255] of Char;// COMMAND string
FData: array[1..1024] of Char;// 数据
end;
//API发送文件
//只做参考
procedure SendFile(const S: TSocket; var BufData: TSendData);
var
HF: HFILE;
Len, Size, Offset: Integer;
begin
//打开文件
HF := OpenFile(BufData.CmdStr);
//偏移位置
Offset := 0;
//文件大小
Size := GetFileSize(HF, nil);
if Size <= 0 then begin
//格式文件总数
BufData.FDataSize := 0;
BufData.FData := '文件不存在,或文件为空值';
WinSock.send(S, BufData, SizeOf(TSendData), 0);
Exit;
end;
repeat
//设置读取偏移位
SetFilePointer(HF, Offset, nil, FILE_CURRENT);
//填充BufData.FData
FillChar(BufData.FData, SizeOf(BufData.FData), #0);
//读取文件到Buf
Len := ReadFileBuffer(HF, BufData.FData, SizeOf(BufData.FData));
//数据长度
BufData.FDataSize := Len;
//累加偏移量
Offset := Offset + Len;
//复位文件
SetFilePointer(HF, 0, nil, FILE_BEGIN);
//发送数据
WinSock.send(S, BufData, SizeOf(TSendData), 0);
until Offset >= Size;
CloseFile(HF);
//格式文件总数
BufData.FDataSize := 0;
FillChar(BufData.FData, SizeOf(BufData.FData), #0);
FormatChar(BufData.FData, '文件大小:%d Byte', [Size]);
WinSock.send(S, BufData, SizeOf(TSendData), 0);
end;
var
HF: HFILE = HFILE_ERROR;
procedure ReadFile(const tempFileName: PChar; const ReadBuf: TSendData; const S: TSocket; H: HWND);
var
StatusText: array[0..1024] of Char;
begin
//读取数据Buffer
if ReadBuf.FDataSize > 0 then begin
if HF = HFILE_ERROR then
HF := CreateFile(tempFileName);
SetFilePointer(HF, 0, nil, FILE_END);
Windows._lwrite(HF, ReadBuf.FData, ReadBuf.FDataSize);
end
else //
begin
//写入到硬盘
CloseFile(HF);
if ReadBuf.FData[0] = #0 then Exit;
FormatChar(StatusText, 'Server Host: [%s], ReadBuf.FData: [%s]',
[Integer(GetRemoteHost(S)), Integer(@ReadBuf.FData)]);
MemoAdd(H, StatusText);
end;
end;