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 _packetParts = new ConcurrentDictionary(); 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); } } } }