⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socketprocess.pas

📁 多线程网络传输 v1.0S_CXV软件,对于多线程的极其有用.
💻 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 + -