Files
HawkeyeVision/framework/Inspectron.HawkEye/DefragmentedPacket.cs
2025-08-19 12:45:50 +02:00

104 lines
2.9 KiB
C#

using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
namespace Inspectron.HawkEye
{
public class DefragmentedPacket
{
private readonly uint _packetSize;
private byte[] _receivedParts = null;
//ConcurrentDictionary<uint,byte[]> _packetParts = new ConcurrentDictionary<uint, byte[]>();
private byte[][] _packetParts;
public DefragmentedPacket(uint packetSize)
{
_packetSize = packetSize;
_packetParts=new byte[30000][];
}
private int _uniquePackets=0;
public void Defragment(byte[] data)
{
var packetStart = -1;
for (int i = 0; i < data.Length; i++)
{
if (BitConverter.ToUInt32(data, i) == 114455)
{
packetStart = i;
break;
};
}
if (packetStart == -1) return;
MemoryStream ms = new MemoryStream(data,packetStart, data.Length - packetStart);
BinaryReader br = new BinaryReader(ms);
br.ReadUInt32();//packetStart
var packetType = br.ReadUInt32();
var sequenceId = br.ReadUInt32();
var packetNumber = br.ReadUInt32();
var totalPackets = br.ReadUInt32();
if(_receivedParts==null)_receivedParts=new byte[totalPackets];
if (_receivedParts[packetNumber] == 1) return;
_receivedParts[packetNumber] = 1;
Interlocked.Increment(ref _uniquePackets);
var dataLen = br.ReadInt32();
var dataBytes = br.ReadBytes(dataLen);
_packetParts[packetNumber] = dataBytes;
}
public byte[] Reconstruct()
{
var parts = _receivedParts.Length;
byte[] res = new byte[parts*_packetSize];
Stopwatch sw = Stopwatch.StartNew();
int resSize = 0;
for (int i = 0; i < parts; i++)
{
//if (_packetParts.ContainsKey((uint) i))
if (_packetParts[i]!=null)
{
var packetData = _packetParts[(uint) i];
Array.Copy(packetData, 0,res, resSize, packetData.Length);
resSize += packetData.Length;
}
else
{
resSize += (int)_packetSize-20/*headerSize*/;
}
}
sw.Stop();
Array.Resize(ref res,resSize);
return res;
}
public bool IsComplete
{
get
{
if (_receivedParts == null) return false;
return _uniquePackets == _receivedParts.Length;
//return _receivedParts.All(x => x == 1);
}
}
}
}