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

📄 iocpherder.pas

📁 iocp远控比较完整的代码.iocp far more complete control of the code
💻 PAS
📖 第 1 页 / 共 2 页
字号:
          if myVideoForm.IsClosing then
          begin
            lp_Io^.IsUsed := False;
            Exit;
          end;
        end;
      end;
    end
    //非视频流数据,而是命令的回复信息,直接发送之
    else if lp_io^.RemoteDataInfo.DataHeaderInfo.DataType = VideoReplay then
    begin
      PostMessage(myVideoForm.Handle, WM_DealDataMsg,
        LOWORD(DWORD(myVideoForm.RemoteCmpedFrameData)),
        HIWORD(DWORD(myVideoForm.RemoteCmpedFrameData)));
      //等待数据出来完毕
      WaitTime := WaitForSingleObject(myVideoForm.MsgDealDataOkNotifyEvent, CWaitTime);
      //如果超时或者出错,则返回错误
      if (WaitTime = WAIT_TIMEOUT) or (WaitTime = WAIT_FAILED) then
      begin
        if myVideoForm.IsClosing then
        begin
          lp_Io^.IsUsed := False;
          Exit;
        end;
      end;
    end;
    //清空缓冲区,复位数据记录
    ZeroMemory(@myVideoForm.tmpDataBuffer, sizeof(myVideoForm.tmpDataBuffer));
    ZeroMemory(@lp_io^.RemoteDataInfo, sizeof(lp_io^.RemoteDataInfo));
    //如果还有剩余的数据,则调用子函数进行处理
    if RemainDataSize > 0 then
    begin
      SubDataBuffer := Pointer(longint(lp_io^.ptrBuffer.buf) +
        longint(lp_io^.ptrBuffer.len) - RemainDataSize);
      SubDataLen := RemainDataSize; 
      //调用处理子函数,接受视频流
      if not ProcessFirstPackegeData(lp_Io, SubDataBuffer, SubDataLen,
        myVideoForm.tmpDataBuffer,
        myVideoForm.RemoteCmpedFrameData,
        myVideoForm.RemoteUnCmpedFrameData,
        myVideoForm.RemoteCmpedFrameArray,
        myVideoForm.RemoteCmpedFrameArray,
        myVideoForm.Handle,
        2, //msh263 压缩
        myVideoForm.MsgDealDataOkNotifyEvent,
        myVideoForm.IsClosing
        )
        then
        begin
          lp_Io^.IsUsed := False;
          Exit;
        end;
    end
  end;
  //重置接收缓冲区的大小
  lp_io.ptrBuffer.len := MAX_BUFSIZE;
end;
 
//文件列表数据处理函数
procedure DealRemoteFileListData(var lp_Io : PPerHandleData);
var
  RemainDataSize : Word;
  SubDataBuffer : Pointer;
  SubDataLen : integer;
  UnCmpFrameDataLen : longint;
  myFileAndInfoCtrlForm : TFileAndInfoCtrlForm;
  WaitTime : DWORD;
begin
  //获取列表类实例
  myFileAndInfoCtrlForm := TFileAndInfoCtrlForm(lp_Io^.AllCtrlInstance.GetSystemInfoInstance);
  //如果是开头数据,则直接子函数进行处理
  if lp_io^.RemoteDataInfo.DataHeaderInfo.CompressedDataSize = 0 then
  begin
    SubDataBuffer := lp_io^.ptrBuffer.buf;
    SubDataLen := lp_io^.ptrBuffer.len;
    //调用处理子函数
    if not ProcessFirstPackegeData(lp_Io, SubDataBuffer, SubDataLen,
      myFileAndInfoCtrlForm.tmpDataBuffer,
      myFileAndInfoCtrlForm.RemoteCmpedFrameData,
      myFileAndInfoCtrlForm.RemoteUnCmpedFrameData,
      myFileAndInfoCtrlForm.RemoteCmpedFrameArray,
      myFileAndInfoCtrlForm.RemoteUnCmpedFrameArray,
      myFileAndInfoCtrlForm.Handle,
      1, //lzo or zlib压缩
      myFileAndInfoCtrlForm.MsgDealDataOkNotifyEvent,
      myFileAndInfoCtrlForm.IsClosing
      )
      then
      begin
        lp_Io^.IsUsed := False;
        Exit;
      end;
  end
  //如果非开头的数据,并且帧内存区域里面的数据+刚收到的数据还是不足一帧数据
  //则直接将刚收到的数据拷贝进帧内存区域------------------------------------(1)
  else if lp_io^.RemoteDataInfo.FilledDataLength + lp_io^.ptrBuffer.len <
    lp_io^.RemoteDataInfo.DataHeaderInfo.CompressedDataSize then
  begin
    //将数据拷贝进帧内存区
    CopyMemory(Pointer(DWORD(myFileAndInfoCtrlForm.RemoteCmpedFrameData) +
      lp_io^.RemoteDataInfo.FilledDataLength),
      lp_io^.ptrBuffer.buf, lp_io^.ptrBuffer.len);
    //增加帧数据内存区的已填充的计数
    Inc(lp_io^.RemoteDataInfo.FilledDataLength, lp_io^.ptrBuffer.len); 
  end
  else
  //如果(1)的条件不成立,说明已经足够一帧数据了,则进行处理
  begin
    RemainDataSize := lp_io^.RemoteDataInfo.FilledDataLength + lp_io^.ptrBuffer.len -
      lp_io^.RemoteDataInfo.DataHeaderInfo.CompressedDataSize;
    //拷贝数据
    if lp_io^.RemoteDataInfo.FilledDataLength <
      lp_io^.RemoteDataInfo.DataHeaderInfo.CompressedDataSize then
    begin
      CopyMemory(Pointer(DWORD(myFileAndInfoCtrlForm.RemoteCmpedFrameData) +
        lp_io^.RemoteDataInfo.FilledDataLength),
        lp_io^.ptrBuffer.buf, lp_io^.RemoteDataInfo.DataHeaderInfo.CompressedDataSize -
        lp_io^.RemoteDataInfo.FilledDataLength);
    end; 
    //解压并进行数据处理
  {$IFDEF _MiniLzo}
    UnCmpFrameDataLen := lp_io^.RemoteDataInfo.DataHeaderInfo.UnCompressedDataSize;
    //申请解压内存
    GetMyMem(UnCmpFrameDataLen, myFileAndInfoCtrlForm.RemoteUnCmpedFrameData,
      myFileAndInfoCtrlForm.RemoteUnCmpedFrameArray);
    DecompressData(myFileAndInfoCtrlForm.RemoteCmpedFrameData,
      lp_io^.RemoteDataInfo.DataHeaderInfo.CompressedDataSize,
      myFileAndInfoCtrlForm.RemoteUnCmpedFrameData);
  {$ELSE}
    //Zlib解压
    UnCmpFrameDataLen := lp_io^.RemoteDataInfo.DataHeaderInfo.UnCompressedDataSize;
    //申请解压内存
    GetMyMem(UnCmpFrameDataLen, myFileAndInfoCtrlForm.RemoteUnCmpedFrameData,
      myFileAndInfoCtrlForm.RemoteUnCmpedFrameArray);
    ZDecompress(myFileAndInfoCtrlForm.RemoteCmpedFrameData,
      lp_io^.RemoteDataInfo.DataHeaderInfo.CompressedDataSize,
      myFileAndInfoCtrlForm.RemoteUnCmpedFrameData,
      UnCmpFrameDataLen);
  {$ENDIF}
    //通知主窗口,新的数据帧已经到了,lParam就是数据本身的指针
    if IsWindow(myFileAndInfoCtrlForm.Handle) then
    begin
      PostMessage(myFileAndInfoCtrlForm.Handle, WM_DealDataMsg,
        LOWORD(DWORD(myFileAndInfoCtrlForm.RemoteCmpedFrameData)),
        HIWORD(DWORD(myFileAndInfoCtrlForm.RemoteCmpedFrameData)));
      //等待数据出来完毕
      WaitTime := WaitForSingleObject(myFileAndInfoCtrlForm.MsgDealDataOkNotifyEvent, CWaitTime);
      //如果超时或者出错,则返回错误
      if (WaitTime = WAIT_TIMEOUT) or (WaitTime = WAIT_FAILED) then
      begin
        if myFileAndInfoCtrlForm.IsClosing then
        begin
          lp_Io^.IsUsed := False;
          Exit;
        end;
      end;
    end; 
    //释放屏幕数据的内存
    if myFileAndInfoCtrlForm.RemoteCmpedFrameData <> nil then
    begin
      FreeMyMem(myFileAndInfoCtrlForm.RemoteCmpedFrameData,
        myFileAndInfoCtrlForm.RemoteCmpedFrameArray);
    end;
    if myFileAndInfoCtrlForm.RemoteUnCmpedFrameData <> nil then
    begin
      FreeMyMem(myFileAndInfoCtrlForm.RemoteUnCmpedFrameData,
        myFileAndInfoCtrlForm.RemoteUnCmpedFrameArray);
    end;
    //清空缓冲区,复位数据记录
    ZeroMemory(@myFileAndInfoCtrlForm.tmpDataBuffer, sizeof(myFileAndInfoCtrlForm.tmpDataBuffer));
    ZeroMemory(@lp_io^.RemoteDataInfo, sizeof(lp_io^.RemoteDataInfo));
    //如果还有剩余的数据,则调用子函数进行处理
    if RemainDataSize > 0 then
    begin
      SubDataBuffer := Pointer(longint(lp_io^.ptrBuffer.buf) +
        longint(lp_io^.ptrBuffer.len) - RemainDataSize);
      SubDataLen := RemainDataSize;
      //调用处理子函数
      if not ProcessFirstPackegeData(lp_Io, SubDataBuffer, SubDataLen,
        myFileAndInfoCtrlForm.tmpDataBuffer,
        myFileAndInfoCtrlForm.RemoteCmpedFrameData,
        myFileAndInfoCtrlForm.RemoteUnCmpedFrameData,
        myFileAndInfoCtrlForm.RemoteCmpedFrameArray,
        myFileAndInfoCtrlForm.RemoteUnCmpedFrameArray,
        myFileAndInfoCtrlForm.Handle,
        1, //lzo or zlib压缩
        myFileAndInfoCtrlForm.MsgDealDataOkNotifyEvent,
        myFileAndInfoCtrlForm.IsClosing 
        )
        then
        begin
          lp_Io^.IsUsed := False;
          Exit;
        end;
    end
  end;
  //重置接收缓冲区的大小
  lp_io.ptrBuffer.len := MAX_BUFSIZE;
end;

//文件数据处理函数--不需要进行粘包处理的
procedure DealRemoteFileData(var lp_Io : PPerHandleData; const FileDataBuffer : Pointer = nil;
  const DataLen : integer = 0);
var
  myFileAndInfoCtrlForm : TFileAndInfoCtrlForm;
  WaitTime : DWORD;
begin
  myFileAndInfoCtrlForm := TFileAndInfoCtrlForm(lp_Io^.AllCtrlInstance.GetSystemInfoInstance);
  if myFileAndInfoCtrlForm.RecvFileStream = nil then Exit;
  if lp_io^.RemoteDataInfo.DataHeaderInfo.DataType = TransmitFileData then
  begin
    if FileDataBuffer = nil then
    begin
      myFileAndInfoCtrlForm.RecvFileStream.Write(lp_Io^.ptrBuffer^.buf^, lp_Io^.ptrBuffer^.len);
      Inc(lp_io^.RemoteDataInfo.FilledDataLength, lp_Io^.ptrBuffer^.len);
    end
    else
    begin
      myFileAndInfoCtrlForm.RecvFileStream.Write(FileDataBuffer^, DataLen);
      Inc(lp_io^.RemoteDataInfo.FilledDataLength, DataLen);
    end;
    //更新进度条
    PostMessage(myFileAndInfoCtrlForm.Handle, WM_FileTransProc,
      HiWord(lp_io^.RemoteDataInfo.FilledDataLength), LOWORD(lp_io^.RemoteDataInfo.FilledDataLength));
  end
  else
  begin
    if FileDataBuffer = nil then
      Inc(lp_io^.RemoteDataInfo.FilledDataLength, lp_Io^.ptrBuffer^.len)
    else
      Inc(lp_io^.RemoteDataInfo.FilledDataLength, DataLen);
    //更新进度条
    PostMessage(myFileAndInfoCtrlForm.Handle, WM_FileTransProc, 0,
      LOWORD(lp_io^.RemoteDataInfo.DataHeaderInfo.CompressedDataSize));
  end;
  //如果文件接受完毕,则进行处理
  if lp_io^.RemoteDataInfo.FilledDataLength >= lp_io^.RemoteDataInfo.DataHeaderInfo.CompressedDataSize then
  begin
    FreeAndNil(myFileAndInfoCtrlForm.RecvFileStream);
    //通知主窗口,一个文件已经接受完毕了
    if IsWindow(myFileAndInfoCtrlForm.Handle) then
    begin
      PostMessage(myFileAndInfoCtrlForm.Handle, WM_OneFileTransOk, 0, 0);
      //等待数据出来完毕
      WaitTime := WaitForSingleObject(myFileAndInfoCtrlForm.MsgDealDataOkNotifyEvent, CWaitTime);
      //如果超时或者出错,则返回错误
      if ((WaitTime = WAIT_TIMEOUT) or (WaitTime = WAIT_FAILED)) and myFileAndInfoCtrlForm.IsClosing then
      begin
        lp_Io^.IsUsed := False;
      end;
    end;
    //清空缓冲区
    ZeroMemory(@myFileAndInfoCtrlForm.tmpDataBuffer, sizeof(myFileAndInfoCtrlForm.tmpDataBuffer));
    ZeroMemory(@lp_io^.RemoteDataInfo, sizeof(lp_io^.RemoteDataInfo));
  end;
  //重置接收缓冲区的大小
  lp_io.ptrBuffer.len := MAX_BUFSIZE;
end;


(*
编译器将会选择编译上述A的那列程序, 日后, 如果我们需要编译「简易版」
的程序版本时, 只要:
? 将{$DEFINE _ProVersion}那列整个删掉。
? 或者, 将{$DEFINE _ProVersion}改成{-$DEFINE _ProVersion}, 
让它变成普通的批注
? 或者, 在{$DEFINE _ProVersion}的下一列加上{$UNDEF _ProVersion},
解除_ProVersion这个条件名称的定义。
这样, 由于_ProVersion这个条件名称未定义的缘故, Compiler就只会选择
{$ELSE}下的那段程序, 重新编译一次, 不需费太多力气, 很容易的就可以制作出
「简易版」了, 省去了要同时维护两份程序的麻烦。






*)



end.

⌨️ 快捷键说明

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