📄 socketprocess.pas
字号:
unit SocketProcess;
interface
uses
Windows,SysUtils,Classes,IdBaseComponent, IdComponent, IdTCPServer,ThreadPublicData;
const packsize=65000;
type TSend=packed record
masmID:Word;
ID:Word;
F1:DWord;
F2:DWord;
F3:DWord;
F4:DWord;
Len:DWord;
MD:Int64;
end;
type TReceive=packed record
masmID:Word;
ID:Word;
F1:DWord;
F2:DWord;
F3:DWord;
F4:DWord;
Len:DWord;
MD:Int64;
Buffer:Array[0..packsize-1] of byte;
end;
type
TSocketProcesser=Class
private
AOne:TidPeerThread;
HeaderFinished,BodyFinished,PushTransporting:Boolean;
RemainBytes:Word;
ReceivedCounter:Integer;//要接收的字节数
Rev:TReceive;
Snd:TSend;
PRev,PSnd:PByte;
TempPointer:PByte;
procedure Branch;//处理周转中心
procedure Echo(Option:Word);
procedure BuildFile;//建立文件内存映像
procedure Pass;//通知客户端可以进行传输
procedure FileTransport;
protected
public
constructor Create(AThread:TidPeerThread);reintroduce;
procedure Process;
published
end;
implementation
uses
Unit1;
procedure TSocketProcesser.Branch;
begin
case Rev.ID of
0:BuildFile;
1:Pass;
2:FileTransport;
3:
begin
UnMapViewOfFile(FileMapPointer);//关闭文件
Form1.Memo1.Lines.Add(FN+','+TimetoStr(Now())+'结束传输');
end;
end;
end;
procedure TSocketProcesser.BuildFile;
var
FileName:String[250];
PS,PD:PByte;
FH1,FH2:THandle;
size:DWord;
begin
PS:=TempPointer;
Inc(PS,32);
PD:=@FileName;
move(PS^,PD^,Rev.Len);
FN:=FileName;
size:=Rev.F1;//得到文件长度
FH1:=FileCreate('Files\'+FileName);
FileClose(FH1);
FH1:=FileOpen('Files\'+FileName,fmOpenreadWrite);
FH2:=CreateFileMapping(FH1,nil,Page_ReadWrite,0,size,nil);
CloseHandle(FH1);
FileMapPointer:=MapViewOfFile(FH2,File_Map_All_Access,0,0,size);
FileSize:=size;//
CloseHandle(FH2);
Form1.Memo1.Lines.Add(FileName+',长度'+inttostr(FileSize)+','+TimetoStr(Now())+'开始传输');
Echo(1);
end;
procedure TSocketProcesser.Pass;//索取数据报
begin
Snd.F1:=Rev.F1+1;//下一个数据报
Snd.F2:=Rev.F2;
Echo(2);
end;
procedure TSocketProcesser.FileTransport;
var
TempFileMapPointer,PB:PByte;
begin
TempFileMapPointer:=FileMapPointer;
PB:=PRev;
Inc(TempFileMapPointer,Rev.F3);
Inc(PB,32);
move(PB^,TempFileMapPointer^,Rev.Len);
IF Rev.F1<Rev.F2 then//请求下一个数据报
Pass
else//如果相等,说明已经接收完毕
Echo(3);
end;
constructor TSocketProcesser.Create(AThread:TidPeerThread);
begin
inherited Create();
AOne:=AThread;
ReceivedCounter:=32;//首先要接收32个字节
HeaderFinished:=False;
BodyFinished:=False;
PushTransporting:=False;
RemainBytes:=0;
PRev:=@Rev;
PSnd:=@Snd;
TempPointer:=PRev;
end;
procedure TSocketProcesser.Process;
var
Bytes:Integer;
begin
IF ReceivedCounter=0 then
exit;
IF RemainBytes>0 then//上次还有字节没收取
begin
ReceivedCounter:=ReceivedCounter-RemainBytes;
IF ReceivedCounter>0 then//接收剩余字节后数据报尚未完成接收
begin
Bytes:=RemainBytes;//接收剩余
RemainBytes:=0;
end
else
begin
IF ReceivedCounter=0 then//剩余字节刚好接收完成
begin
Bytes:=RemainBytes;
RemainBytes:=0;
IF HeaderFinished then
BodyFinished:=True
else
begin
HeaderFinished:=True;//如果头完成就是体完成,否则只是头完成
PushTransporting:=True;
end;
end
else
begin //剩余字节超过本数据报大小,产生数据粘连
Bytes:=ReceivedCounter+RemainBytes;
RemainBytes:=RemainBytes-Bytes;//完成本数据报后剩余字节
IF HeaderFinished then
BodyFinished:=True
else
begin
HeaderFinished:=True;//如果头完成就是体完成,否则只是头完成
PushTransporting:=True;
end;
end;
end;
AOne.Connection.ReadBuffer(TempPointer^,Bytes);
Inc(TempPointer,Bytes);
IF (Rev.Len=0) and HeaderFinished then//只要头
begin
HeaderFinished:=False;
PushTransporting:=False;
TempPointer:=PRev;
ReceivedCounter:=32;//准备下一个头
Branch;//分支处理
end
else
begin
IF PushTransporting then //正在传输body
begin
PushTransporting:=False;
ReceivedCounter:=Rev.Len;
end
else
IF BodyFinished then
begin
TempPointer:=PRev;
HeaderFinished:=False;
BodyFinished:=False;
ReceivedCounter:=32;//准备下一个头
Branch;//分支处理
end
end;
end
else
begin
Try
RemainBytes:=AOne.Connection.ReadFromStack(True,15000,True);
Except
exit;
end;
end;
end;
procedure TSocketProcesser.Echo(Option: Word);
begin
Snd.ID:=Option;
Snd.Len:=0;
AOne.Connection.Socket.Send(PSnd^,32);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -