internal static string Bytes2StringWithLength(Stream stream) { string s = ""; byte[] buff = HelperTools.RentBuffer(256); if (stream.Read(buff, 0, 4) == 4) { int length = BitConverter.ToInt32(buff, 0); if (stream.Read(buff, 0, length) == length) { s = Encoding.ASCII.GetString(buff, 0, length); } } return(s); //int stringLength = BitConverter.ToInt32(_buff, _offset); //if (stringLength > 0 && stringLength < _buff.Length - _offset) //{ // s = Encoding.ASCII.GetString(_buff, _offset + 4, stringLength); //} //return s; }
//public bool RemovePeer(string _id) //{ // if (CurrentState != State.Stoped) // return false; // return udpSenders.Remove(HelperTools.GetDeterministicHashCode(_id)); //} /// <summary> /// Resets the ID Peer to its default /// </summary> /// <param name="_id">ID of the peer</param> /// <param name="pOriginal">Returns the default peer tha was present in the file</param> /// <returns></returns> public bool RemoveReplayAddress(string _id, out PlayPeerInfo pOriginal) { pOriginal = null; if (CurrentState != State.Stoped) { return(false); } int hashedID = HelperTools.GetDeterministicHashCode(_id); if (udpSenders.TryGetValue(hashedID, out PlayPeerInfo p)) { var original = udpSendersOriginal[hashedID]; p.IP = original.IP; p.Port = original.Port; p.NIC = original.NIC; pOriginal = original; return(true); } return(false); }
internal static ulong IPPort2Long(string _ip, int _port) { byte[] _buffer = new byte[8]; ushort[] ipChunks = new ushort[4]; string[] chunks = _ip.Split('.'); if (chunks.Length == 4) { for (int i = 0; i < 4; i++) { ipChunks[i] = ushort.Parse(chunks[i]); } } // IP 4 for (int i = 0; i < 4; i++) { _buffer[i] = (byte)ipChunks[i]; } // Port 4 HelperTools.Int32Bytes(_buffer, 4, _port); return(BitConverter.ToUInt64(_buffer, 0)); }
/// <summary> /// Enables or disables a given peer by ID /// </summary> /// <param name="_id">ID of the peer</param> /// <param name="enabled">Enable if true, disable if false</param> public void SetPeerEnabled(string _id, bool enabled) { int hashedID = HelperTools.GetDeterministicHashCode(_id); if (udpSenders.TryGetValue(hashedID, out PlayPeerInfo p)) { p.IsEnabled = enabled; } }
private void WriteHeader(long _time, string _ID, int _size, uint _ip, int _port) { Span <byte> headerSpan = stackalloc byte[HelperTools.headerSize]; // Time 8 BinaryPrimitives.WriteInt64LittleEndian(headerSpan, _time); // Hashed ID 4 BinaryPrimitives.WriteInt32LittleEndian(headerSpan.Slice(8), HelperTools.GetDeterministicHashCode(_ID)); // IP 4 BinaryPrimitives.WriteUInt32LittleEndian(headerSpan.Slice(12), _ip); // Port 4 BinaryPrimitives.WriteInt32LittleEndian(headerSpan.Slice(16), _port); // Size 4 BinaryPrimitives.WriteInt32LittleEndian(headerSpan.Slice(20), _size); // Write file.Write(headerSpan); }
/// <summary> /// Retrieves information from the recording idx file /// </summary> /// <param name="_idxFilePath"></param> /// <returns>Peers, recording date and time, duration in secs, recording size in bytes</returns> public static (ICollection <PlayPeerInfo>, DateTime, int, long) GetRecordingInfo(string _idxFilePath) { int duration = 0; int nPeers = 0; int secsIdxInterval = 0; DateTime date = DateTime.MinValue; List <PlayPeerInfo> peers = new List <PlayPeerInfo>(); using (FileStream idxFile = new FileStream(_idxFilePath, FileMode.Open, FileAccess.Read)) using (BinaryReader idxBinaryReader = new BinaryReader(idxFile)) { Span <byte> auxBuff = stackalloc byte[1024]; // Read DateTime, Secs Interval and Peers info date = HelperTools.fromMillis(idxBinaryReader.ReadInt64()); secsIdxInterval = idxBinaryReader.ReadInt32(); nPeers = idxBinaryReader.ReadInt32(); // Read peers for (int i = 0; i < nPeers; i++) { string ID = HelperTools.Bytes2StringWithLength(idxFile); string IP = HelperTools.Bytes2StringWithLength(idxFile); int Port = idxBinaryReader.ReadInt32(); peers.Add(new PlayPeerInfo { ID = ID, IP = IP, Port = Port }); } // Guess duration FileInfo fInfo = new FileInfo(_idxFilePath); duration = ((int)((fInfo.Length - idxBinaryReader.BaseStream.Position) / HelperTools.idxIndexSize)) * secsIdxInterval; } string rawFile = Path.Combine(Path.GetDirectoryName(_idxFilePath), Path.GetFileNameWithoutExtension(_idxFilePath)) + ".raw"; FileInfo fRaw = new FileInfo(rawFile); return(peers, date, duration, fRaw.Length); }
/// <summary> /// Override the default destination ip of a recorded peer with a given one. /// </summary> /// <param name="_ID">ID of the peer</param> /// <param name="_dstIP">New destination IP</param> /// <param name="_dstPort">New destination Port</param> /// <param name="_nic">NIC to send data from</param> /// <returns></returns> public bool AddReplayAddress(string _ID, string _dstIP, int _dstPort, string _nic) { if (CurrentState != State.Stoped) { return(false); } int hashedID = HelperTools.GetDeterministicHashCode(_ID); if (udpSenders.TryGetValue(hashedID, out PlayPeerInfo p)) { p.IP = _dstIP; p.Port = _dstPort; p.NIC = _nic; return(true); } return(false); }
private void FillIDXHeader(FileStream _idxFile) { Span <byte> idxHeader = stackalloc byte[4096]; // Time of recording BinaryPrimitives.WriteInt64LittleEndian(idxHeader, HelperTools.millisFromEpochNow()); // Interval BinaryPrimitives.WriteInt32LittleEndian(idxHeader.Slice(8), secsIdxInterval); // Number of peers BinaryPrimitives.WriteInt32LittleEndian(idxHeader.Slice(12), socketListeners.Count); // Peer info int nBytes = 16; foreach (RecPeerInfo p in socketListeners.Values) { nBytes += HelperTools.StringWithLength2Bytes(idxHeader.Slice(nBytes), p.ID); nBytes += HelperTools.StringWithLength2Bytes(idxHeader.Slice(nBytes), p.IP); BinaryPrimitives.WriteInt32LittleEndian(idxHeader.Slice(nBytes), p.Port); nBytes += 4; } idxFile.Write(idxHeader.Slice(0, nBytes)); }
private void RunReaderSenderProcessCallback(string _filePath, string _idxFilePath, CancellationToken token) { ulong ip; int n_bytes = 0, size = 0; int hashedID = 0; long timeoffset = 0, waitTime = 0, nowTime = 0, time = 0; int lastTimeStatusS = 0, timeStatusS = 0; // Increase timers resolution WinAPI.WinAPITime.TimeBeginPeriod(1); // Open file using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { if (has2UpdatePosition) { file.Seek(newPosition, SeekOrigin.Begin); has2UpdatePosition = false; resetTimeOffsetRequired = true; } while (!token.IsCancellationRequested) { // Paused if (CurrentState == State.Paused) { Thread.Sleep(500); } else { if ((n_bytes = file.Read(buffer, 0, HelperTools.headerSize)) == HelperTools.headerSize) { // Get fields replayTime = time = BitConverter.ToInt64(buffer, 0); hashedID = BitConverter.ToInt32(buffer, 8); ip = BitConverter.ToUInt64(buffer, 12); size = BitConverter.ToInt32(buffer, 20); // Update time in secs timeStatusS = (int)(replayTime / 1000_000); // Read Payload n_bytes = file.Read(buffer, 0, size); nowTime = HelperTools.GetLocalMicrosTime(); if (resetTimeOffsetRequired) { timeoffset = nowTime - time; waitTime = 0; resetTimeOffsetRequired = false; } else { nowTime -= timeoffset; waitTime = time - nowTime; if (waitTime > 1000) // 1ms { Thread.Sleep((int)(waitTime / 1000)); } } // Send Send(hashedID, buffer, 0, n_bytes); // Update Progress if (timeStatusS != lastTimeStatusS) { ProgressEvent?.Invoke(timeStatusS); lastTimeStatusS = timeStatusS; } if (has2UpdatePosition) { file.Seek(newPosition, SeekOrigin.Begin); has2UpdatePosition = false; resetTimeOffsetRequired = true; } } else { // End of File cancelSource.Cancel(); // Update Stop Status CurrentState = State.Stoped; StatusEvent?.Invoke(CurrentState); foreach (var k in _dataRate.Keys.ToList()) { _dataRate[k] = 0; } DataRateEvent?.Invoke(_dataRate); // rewind Seek(0); eventTimer.Dispose(); eventTimer = null; ProgressEvent?.Invoke(0); } } } } WinAPI.WinAPITime.TimeEndPeriod(1); }
/// <summary> /// Load a recording file /// </summary> /// <param name="_filePath">Raw file path</param> /// <param name="_startTime">out Start date and time</param> /// <param name="_lastTime">out Last time in recording</param> /// <returns>Collection of peers recorded in the file</returns> public ICollection <PlayPeerInfo> LoadFile(string _filePath, out DateTime _startTime, out int _lastTime) { if (CurrentState != State.Stoped) { throw new InvalidOperationException("Playing in progress. Must stop to load file"); } filePath = _filePath; idxFilePath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath)) + ".idx"; // Init stuff _lastTime = 0; _startTime = DateTime.MinValue; timeIndexes.Clear(); int nPeers = 0; udpSendersOriginal.Clear(); udpSenders.Clear(); _dataRate.Clear(); using (FileStream idxFile = new FileStream(idxFilePath, FileMode.Open, FileAccess.Read)) using (BinaryReader idxBinaryReader = new BinaryReader(idxFile)) { int time = 0; long position = 0; Span <byte> auxBuff = stackalloc byte[4096]; // Read DateTime, Secs Interval and Peers info RecDateTime = _startTime = HelperTools.fromMillis(idxBinaryReader.ReadInt64()); secsIdxInterval = idxBinaryReader.ReadInt32(); nPeers = idxBinaryReader.ReadInt32(); // Read peers for (int i = 0; i < nPeers; i++) { string ID = HelperTools.Bytes2StringWithLength(idxFile); string IP = HelperTools.Bytes2StringWithLength(idxFile); int Port = idxBinaryReader.ReadInt32(); udpSenders.Add(HelperTools.GetDeterministicHashCode(ID), new PlayPeerInfo { ID = ID, IP = IP, Port = Port }); udpSendersOriginal.Add(HelperTools.GetDeterministicHashCode(ID), new PlayPeerInfo { ID = ID, IP = IP, Port = Port }); _dataRate[ID] = 0f; } Span <byte> timeBuff = stackalloc byte[HelperTools.idxIndexSize]; // Get All times to cache while (idxFile.Read(timeBuff) == HelperTools.idxIndexSize) { time = BinaryPrimitives.ReadInt32LittleEndian(timeBuff); position = BinaryPrimitives.ReadInt64LittleEndian(timeBuff.Slice(4)); try { timeIndexes.Add(time, position); } catch (Exception e) { logger.Error(e, "Error reading idx file. TimeIndexes"); } } _lastTime = lastTime = time; } return(udpSenders.Values); }