封包队列源码
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.