104 lines
2.9 KiB
C#
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);
|
|
}
|
|
}
|
|
|
|
}
|
|
} |