📄 iocpherder.pas
字号:
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 + -