?? 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 + -