From 1dffe235ff77bc402f2a896f62366883eb4e31d3 Mon Sep 17 00:00:00 2001 From: "phares@iscn5cg20977xq" Date: Tue, 9 Sep 2025 17:41:29 -0700 Subject: [PATCH] transmission-control-protocol-helper --- File-Watcher.csproj | 2 +- Helpers/HelperSerial.cs | 2 +- Helpers/TransmissionControlProtocolHelper.cs | 129 ++++++++++++++++++ ...ransmissionControlProtocolConfiguration.cs | 4 +- Worker.cs | 1 + 5 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 Helpers/TransmissionControlProtocolHelper.cs diff --git a/File-Watcher.csproj b/File-Watcher.csproj index 4547d86..dcc92be 100644 --- a/File-Watcher.csproj +++ b/File-Watcher.csproj @@ -20,7 +20,7 @@ - + diff --git a/Helpers/HelperSerial.cs b/Helpers/HelperSerial.cs index 1c86630..124cdd3 100644 --- a/Helpers/HelperSerial.cs +++ b/Helpers/HelperSerial.cs @@ -125,7 +125,7 @@ internal static partial class HelperSerial // } byte[] documentDelimiter = [ - Convert.ToByte(32), + Convert.ToByte(32), Convert.ToByte(83), Convert.ToByte(116), Convert.ToByte(97), diff --git a/Helpers/TransmissionControlProtocolHelper.cs b/Helpers/TransmissionControlProtocolHelper.cs new file mode 100644 index 0000000..cb789c8 --- /dev/null +++ b/Helpers/TransmissionControlProtocolHelper.cs @@ -0,0 +1,129 @@ +using File_Watcher.Models; +using System.Net.Sockets; +using System.Text; + +namespace File_Watcher.Helpers; + +internal static partial class TransmissionControlProtocolHelper +{ + + private record Record(BinaryReader BinaryReader, + BinaryWriter BinaryWriter, + NetworkStream NetworkStream, + List ReadTimes); + + private static long _LastWrite; + private static Record? _Record; + private static readonly object _Lock = new(); + + private static void ReadFiles(TransmissionControlProtocolConfiguration tcpConfiguration, ILogger logger) + { + List bytes = []; + // byte nullByte = Convert.ToByte('\0'); + string directory = GetDirectory(tcpConfiguration); + string[] files = Directory.GetFiles(directory, $"{tcpConfiguration.IPAddress}-*.raw", SearchOption.TopDirectoryOnly); + logger.LogInformation("Read {count} files", files.Length); + foreach (string file in files) + { + foreach (byte @byte in File.ReadAllBytes(file)) + { + // if (@byte.Equals(nullByte)) + // continue; + bytes.Add(@byte); + } + } + if (bytes.Count > 0) + { + string bytesFile = Path.Combine(directory, $"{tcpConfiguration.IPAddress}-{DateTime.Now.Ticks}.pcl"); + File.WriteAllBytes(bytesFile, bytes.ToArray()); + foreach (string file in files) + File.Delete(file); + } + } + + private static void CreateClient(AppSettings appSettings, ILogger logger) + { + logger.LogDebug(appSettings.TransmissionControlProtocolConfiguration.IPAddress); + TcpClient tcpClient = new(appSettings.TransmissionControlProtocolConfiguration.IPAddress, appSettings.TransmissionControlProtocolConfiguration.Port); + NetworkStream networkStream = tcpClient.GetStream(); + _Record = new(BinaryReader: new(networkStream), BinaryWriter: new(networkStream), NetworkStream: networkStream, ReadTimes: []); + } + + private static string GetDirectory(TransmissionControlProtocolConfiguration tcpConfiguration) + { + string result = Path.GetFullPath(Path.Combine(tcpConfiguration.Destination, tcpConfiguration.IPAddress)); + if (!Directory.Exists(result)) + _ = Directory.CreateDirectory(result); + return result; + } + + private static void NetworkStreamCanRead(TransmissionControlProtocolConfiguration tcpConfiguration, ILogger logger, NetworkStream networkStream) + { + List results = []; + byte[] bytes = new byte[1024]; + string directory = GetDirectory(tcpConfiguration); + do + { + int count = networkStream.Read(bytes, 0, bytes.Length); + if (count > 0) + results.AddRange(bytes.Take(count)); + } + while (networkStream.DataAvailable); + logger.LogInformation("Read {count} bytes", results.Count); + if (results.Count > 0) + { + bytes = results.ToArray(); + File.WriteAllBytes(Path.Combine(directory, $"{tcpConfiguration.IPAddress}-{DateTime.Now.Ticks}.raw"), bytes); + if (!string.IsNullOrEmpty(tcpConfiguration.DelimiterPattern)) + { + string content = Encoding.ASCII.GetString(bytes); + logger.LogDebug("Content {content}", content); + if (content.Contains(tcpConfiguration.DelimiterPattern)) + ReadFiles(tcpConfiguration, logger); + } + } + } + + internal static bool ReadWrite(AppSettings appSettings, ILogger logger) + { + lock (_Lock) + { + if (!appSettings.TransmissionControlProtocolConfiguration.Server && _Record is not null && appSettings.TransmissionControlProtocolConfiguration.DelimiterSeconds > 0) + { + TimeSpan? timeSpan = _Record.ReadTimes.Count == 0 ? null : new(DateTime.Now.Ticks - _Record.ReadTimes[^1]); + if (timeSpan is not null && timeSpan.Value.TotalSeconds > appSettings.TransmissionControlProtocolConfiguration.DelimiterSeconds) + { + ReadFiles(appSettings.TransmissionControlProtocolConfiguration, logger); + _Record.ReadTimes.Clear(); + } + } + if (!appSettings.TransmissionControlProtocolConfiguration.Server && _Record is not null) + { + TimeSpan timeSpan = new(DateTime.Now.Ticks - _LastWrite); + if (_LastWrite == 0 || timeSpan.TotalMinutes > 1) + { + try + { + _Record.NetworkStream.WriteByte(Convert.ToByte('\0')); + _LastWrite = DateTime.Now.Ticks; + } + catch (Exception) + { } + } + } + if (!appSettings.TransmissionControlProtocolConfiguration.Server && (_Record?.NetworkStream is null || !_Record.NetworkStream.Socket.Connected)) + CreateClient(appSettings, logger); + else if (appSettings.TransmissionControlProtocolConfiguration.Server) + throw new NotImplementedException($"Use {nameof(HelperTCP)}"); + if (_Record?.NetworkStream is not null && _Record.NetworkStream.CanRead && _Record.NetworkStream.DataAvailable) + { + _Record.ReadTimes.Add(DateTime.Now.Ticks); + NetworkStreamCanRead(appSettings.TransmissionControlProtocolConfiguration, logger, _Record.NetworkStream); + } + if (appSettings.TransmissionControlProtocolConfiguration.Server && _Record?.NetworkStream is not null && _Record.NetworkStream.CanWrite) + throw new NotImplementedException($"Use {nameof(HelperTCP)}"); + } + return true; + } + +} \ No newline at end of file diff --git a/Models/TransmissionControlProtocolConfiguration.cs b/Models/TransmissionControlProtocolConfiguration.cs index baeeeae..2504af9 100644 --- a/Models/TransmissionControlProtocolConfiguration.cs +++ b/Models/TransmissionControlProtocolConfiguration.cs @@ -3,7 +3,9 @@ using System.Text.Json.Serialization; namespace File_Watcher.Models; -public record TransmissionControlProtocolConfiguration(string Destination, +public record TransmissionControlProtocolConfiguration(string DelimiterPattern, + int DelimiterSeconds, + string Destination, string GhostPCLFileName, string IPAddress, int Port, diff --git a/Worker.cs b/Worker.cs index dd9ce5e..1288f6f 100644 --- a/Worker.cs +++ b/Worker.cs @@ -91,6 +91,7 @@ public partial class Worker : BackgroundService nameof(Helpers.HelperMetrologyFiles) => Helpers.HelperMetrologyFiles.SortAndDelete(_AppSettings, _Logger), nameof(Helpers.NationalInstrumentsHelper) => Helpers.NationalInstrumentsHelper.WriteData(_AppSettings, _Logger), nameof(Helpers.DeterministicHashCodeHelper) => Helpers.DeterministicHashCodeHelper.WindowsWork(_AppSettings, _Logger), + nameof(Helpers.TransmissionControlProtocolHelper) => Helpers.TransmissionControlProtocolHelper.ReadWrite(_AppSettings, _Logger), #if Selenium nameof(Helpers.SeleniumHelper) => Helpers.SeleniumHelper.HyperTextMarkupLanguageToPortableNetworkGraphics(_AppSettings, _Logger), #endif