封包队列源码

unit uPacketStream;

interface

uses
System.Classes, System.SysUtils;

type
TPacketStream = class helper for TMemoryStream
public
procedure MoveOffset(const Offset, MemSize: Int64);
end;

var
PacketStream: TMemoryStream;

implementation


procedure TPacketStream.MoveOffset(const Offset, MemSize: Int64);
var
FNewBuffer: TBytes;
begin
if not (MemSize > 0) then
begin
Self.Clear;
Exit;
end;

SetLength(FNewBuffer, MemSize);
Self.Position := Offset;
Self.Read(FNewBuffer[0], Length(FNewBuffer));

Self.Clear;
Self.Write(FNewBuffer[0], Length(FNewBuffer));
end;

(*
function TPacketStream.MoveOffset(const Offset, MemSize: Int64): Boolean;
var
FNewBuffer: TStream;
begin
FNewBuffer := TMemoryStream.Create;
try
Self.Position := Offset;
FNewBuffer.Size := MemSize;
FNewBuffer.CopyFrom(Self, MemSize);
FNewBuffer.Position := 0;

Self.Clear;
Self.Position := 0;
Self.CopyFrom(FNewBuffer, FNewBuffer.Size);
Self.Position := 0;
finally
FNewBuffer.Free;
end;
end;
*)

initialization
PacketStream := TMemoryStream.Create;

finalization
PacketStream.Free;


end.
unit uTCPMerge;

interface

uses
uPacketStream, System.SysUtils {$IFDEF DEBUG},CodeSiteLogging, uFunctions{$ENDIF};

type
TPacketQueue = packed record
Data: TByteArray;
Size: Integer;
end;

function GetPacket(Rcvd: TByteArray; RcvdSize: Integer): TPacketQueue;

implementation

function GetPacket(Rcvd: TByteArray; RcvdSize: Integer): TPacketQueue;
var
PacketStreamSize, Offset, TempOffset, NextOffset: Int64;
LocalPacket: TBytes;
begin
PacketStream.Write(Rcvd[0], RcvdSize);
PacketStreamSize := PacketStream.Size;

{$IF DEFINED(DEBUG) and DEFINED(LOGGER)}
CodeSite.Send('Received : ' + To_Hex(@Rcvd, RcvdSize));
{$IFEND}

Result.Size := 0;
Offset := 0;
TempOffset := 0;
while Offset < PacketStreamSize do
begin
PacketStreamSize := PacketStream.Size;
PacketStream.Position := 0;
SetLength(LocalPacket, PacketStreamSize);
PacketStream.Read(LocalPacket[0], PacketStreamSize);

if not (Length(LocalPacket)) > 0 then
Exit;

{$IF DEFINED(DEBUG) and DEFINED(LOGGER)}
CodeSite.Send('LocalPacket: ' + To_Hex(@LocalPacket[0], Length(LocalPacket)));
{$IFEND}

case LocalPacket[0] of
$C1, $C3: NextOffset := LocalPacket[1];
$C2, $C4: NextOffset := (LocalPacket[1] shl 8) + LocalPacket[2];
else
begin
PacketStream.MoveOffset(Offset, PacketStreamSize);

{$IF DEFINED(DEBUG) and DEFINED(LOGGER)}
CodeSite.Send('Wrong hdr: ' + IntToHex(LocalPacket[0], 1) +' offset: '+ IntToStr(offset));
{$IFEND}

Exit;
end;
end;

if (NextOffset <= PacketStreamSize) then
begin
Move(LocalPacket[0], Result.Data[TempOffset], NextOffset);
Result.Size := Result.Size + NextOffset;

{$IF DEFINED(DEBUG) and DEFINED(LOGGER)}
CodeSite.Send('Result: ' + To_Hex(@Result[TempOffset], NextOffset));
CodeSite.SendFmtMsg('NextOffset: %d; PacketStreamSize: %d',[NextOffset, PacketStreamSize]);
{$IFEND}

Inc(TempOffset, NextOffset);

if (NextOffset = PacketStreamSize) then
begin
{$IF DEFINED(DEBUG) and DEFINED(LOGGER)}
CodeSite.Send('1# END LOOP!!!!');
{$IFEND}

PacketStream.Clear;
LocalPacket := nil;

FillChar(Rcvd, $7FFF, 0);

Exit;
end
else
PacketStream.MoveOffset(NextOffset, PacketStreamSize - NextOffset);

PacketStreamSize := PacketStream.Size;
Continue;
end;

if (NextOffset = 0) then
Exit;
Inc(Offset, NextOffset);
LocalPacket := nil;
end;

{$IF DEFINED(DEBUG) and DEFINED(LOGGER)}
CodeSite.Send('2# END LOOP!!!!');
{$IFEND}

LocalPacket := nil;
FillChar(Rcvd, $7FFF, 0);
end;

end.
nit uFunctions;

interface

uses
System.SysUtils;

function To_Hex(Buffer: PByteArray; Len: Integer) :String;

implementation

function To_Hex(Buffer: PByteArray; Len: Integer) :String;
var
i: integer;
begin
Result := '';
for i := 0 to Len - 1 do
begin
Result := Result + ' ' +IntToHex(Buffer[i],2);
end;
end;

end.

posted @ 2018-03-28 18:35  大龙软件工作室  阅读(184)  评论(0编辑  收藏  举报