From d537761f12e985326b27116ec5407cce3c1ddde5 Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 13:29:41 +0300 Subject: [PATCH 01/22] fix: namespace issues --- NetSdrClientApp/Networking/IUdpClient.cs | 5 ++++- NetSdrClientApp/Networking/UdpClientWrapper.cs | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/NetSdrClientApp/Networking/IUdpClient.cs b/NetSdrClientApp/Networking/IUdpClient.cs index b1732f8..7508c37 100644 --- a/NetSdrClientApp/Networking/IUdpClient.cs +++ b/NetSdrClientApp/Networking/IUdpClient.cs @@ -1,4 +1,7 @@ - +using System; +using System.Threading.Tasks; + +namespace NetSdrClientApp.Networking; public interface IUdpClient { event EventHandler? MessageReceived; diff --git a/NetSdrClientApp/Networking/UdpClientWrapper.cs b/NetSdrClientApp/Networking/UdpClientWrapper.cs index ca88a33..0f325da 100644 --- a/NetSdrClientApp/Networking/UdpClientWrapper.cs +++ b/NetSdrClientApp/Networking/UdpClientWrapper.cs @@ -6,6 +6,8 @@ using System.Threading; using System.Threading.Tasks; +namespace NetSdrClientApp.Networking; + public class UdpClientWrapper : IUdpClient { private readonly IPEndPoint _localEndPoint; From c1b2c7d62c45af2fb4664282321d06d3b9d9bc18 Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 13:33:28 +0300 Subject: [PATCH 02/22] fix: memory leaks --- NetSdrClientApp/Networking/TcpClientWrapper.cs | 1 + NetSdrClientApp/Networking/UdpClientWrapper.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/NetSdrClientApp/Networking/TcpClientWrapper.cs b/NetSdrClientApp/Networking/TcpClientWrapper.cs index 7641e7c..ba300f0 100644 --- a/NetSdrClientApp/Networking/TcpClientWrapper.cs +++ b/NetSdrClientApp/Networking/TcpClientWrapper.cs @@ -57,6 +57,7 @@ public void Disconnect() if (Connected) { _cts?.Cancel(); + _cts?.Dispose(); _stream?.Close(); _tcpClient?.Close(); diff --git a/NetSdrClientApp/Networking/UdpClientWrapper.cs b/NetSdrClientApp/Networking/UdpClientWrapper.cs index 0f325da..18c2941 100644 --- a/NetSdrClientApp/Networking/UdpClientWrapper.cs +++ b/NetSdrClientApp/Networking/UdpClientWrapper.cs @@ -52,6 +52,7 @@ public void StopListening() try { _cts?.Cancel(); + _cts?.Dispose(); _udpClient?.Close(); Console.WriteLine("Stopped listening for UDP messages."); } From e694b824bada5a98bbcd3cc65c829334d196bb85 Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 13:36:25 +0300 Subject: [PATCH 03/22] fix: Equals / GetHashCode --- NetSdrClientApp/Networking/UdpClientWrapper.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NetSdrClientApp/Networking/UdpClientWrapper.cs b/NetSdrClientApp/Networking/UdpClientWrapper.cs index 18c2941..3300bd9 100644 --- a/NetSdrClientApp/Networking/UdpClientWrapper.cs +++ b/NetSdrClientApp/Networking/UdpClientWrapper.cs @@ -62,6 +62,12 @@ public void StopListening() } } + public override bool Equals(object? obj) + { + return obj is UdpClientWrapper other && + _localEndPoint.Equals(other._localEndPoint); + } + public override int GetHashCode() { var payload = $"{nameof(UdpClientWrapper)}|{_localEndPoint.Address}|{_localEndPoint.Port}"; From 8e136de60f43ad42b0aba67c48c81f8a8dae2c62 Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 13:51:45 +0300 Subject: [PATCH 04/22] test: use async Task.Delay instead of Thread.Sleep, and use mock in return value --- EchoServerTests/EchoServerTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EchoServerTests/EchoServerTests.cs b/EchoServerTests/EchoServerTests.cs index 0ffa0c9..812d66e 100644 --- a/EchoServerTests/EchoServerTests.cs +++ b/EchoServerTests/EchoServerTests.cs @@ -8,20 +8,20 @@ namespace EchoTcpServerApp.Wrappers; public class EchoServerLogicTests { [Test] - public void StartAsync_ShouldCallListenerStart() + public async Task StartAsync_ShouldCallListenerStart() { // Arrange var listenerMock = new Mock(); listenerMock.Setup(l => l.AcceptTcpClientAsync()) - .Returns(async () => { await Task.Delay(-1); return null; }); + .Returns(async () => { await Task.Delay(-1); return new Mock().Object; }); var server = new EchoServer(listenerMock.Object); // Act _ = Task.Run(() => server.StartAsync()); - Thread.Sleep(50); + await Task.Delay(50); // Assert listenerMock.Verify(l => l.Start(), Times.Once); From 12d84b135f47b3545a878c48e8b8c5c29de81ad1 Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 14:58:32 +0300 Subject: [PATCH 05/22] refactor: add "readonly" and "static" --- EchoTcpServer/Program.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EchoTcpServer/Program.cs b/EchoTcpServer/Program.cs index f1755e7..2ad22e6 100644 --- a/EchoTcpServer/Program.cs +++ b/EchoTcpServer/Program.cs @@ -19,7 +19,7 @@ namespace EchoTcpServerApp; public class EchoServer { private readonly ITcpListenerWrapper _listener; - private CancellationTokenSource _cancellationTokenSource; + private readonly CancellationTokenSource _cancellationTokenSource; public EchoServer(ITcpListenerWrapper listener) @@ -52,7 +52,7 @@ public async Task StartAsync() Console.WriteLine("Server shutdown."); } - private async Task HandleClientAsync(ITcpClientWrapper client, CancellationToken token) + private static async Task HandleClientAsync(ITcpClientWrapper client, CancellationToken token) { using (NetworkStream stream = client.GetStream()) { From 290c249748eb02118b34379a219372632fc29871 Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 14:59:39 +0300 Subject: [PATCH 06/22] refactor: use modern Memory for work with memory --- EchoTcpServer/Program.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/EchoTcpServer/Program.cs b/EchoTcpServer/Program.cs index 2ad22e6..4628517 100644 --- a/EchoTcpServer/Program.cs +++ b/EchoTcpServer/Program.cs @@ -61,10 +61,13 @@ private static async Task HandleClientAsync(ITcpClientWrapper client, Cancellati byte[] buffer = new byte[8192]; int bytesRead; - while (!token.IsCancellationRequested && (bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, token)) > 0) + while (!token.IsCancellationRequested) { + bytesRead = await stream.ReadAsync(buffer.AsMemory(), token); + if (bytesRead == 0) break; + // Echo back the received message - await stream.WriteAsync(buffer, 0, bytesRead, token); + await stream.WriteAsync(buffer.AsMemory(0, bytesRead), token); Console.WriteLine($"Echoed {bytesRead} bytes to the client."); } } From 0ef4f98c566850f9882dfb1aebf6009f3827e1f9 Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 15:19:57 +0300 Subject: [PATCH 07/22] refactor: add "?" for nullable values --- EchoTcpServer/Program.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EchoTcpServer/Program.cs b/EchoTcpServer/Program.cs index 4628517..0ce5ea0 100644 --- a/EchoTcpServer/Program.cs +++ b/EchoTcpServer/Program.cs @@ -127,7 +127,7 @@ public class UdpTimedSender : IDisposable private readonly string _host; private readonly int _port; private readonly UdpClient _udpClient; - private Timer _timer; + private Timer? _timer; public UdpTimedSender(string host, int port) { @@ -146,7 +146,7 @@ public void StartSending(int intervalMilliseconds) ushort i = 0; - private void SendMessageCallback(object state) + private void SendMessageCallback(object? state) { try { From 6825632cdc0a4b63a93ee663b053f8a03844a7d7 Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 15:22:19 +0300 Subject: [PATCH 08/22] fix: IDisposable pattern --- EchoTcpServer/Program.cs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/EchoTcpServer/Program.cs b/EchoTcpServer/Program.cs index 0ce5ea0..e07088c 100644 --- a/EchoTcpServer/Program.cs +++ b/EchoTcpServer/Program.cs @@ -128,6 +128,7 @@ public class UdpTimedSender : IDisposable private readonly int _port; private readonly UdpClient _udpClient; private Timer? _timer; + private bool _disposed = false; public UdpTimedSender(string host, int port) { @@ -144,7 +145,7 @@ public void StartSending(int intervalMilliseconds) _timer = new Timer(SendMessageCallback, null, 0, intervalMilliseconds); } - ushort i = 0; + private ushort i = 0; private void SendMessageCallback(object? state) { @@ -173,10 +174,23 @@ public void StopSending() _timer?.Dispose(); _timer = null; } + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + StopSending(); + _udpClient.Dispose(); + } + _disposed = true; + } + } public void Dispose() { - StopSending(); - _udpClient.Dispose(); + Dispose(true); + GC.SuppressFinalize(this); } } \ No newline at end of file From 2c83bcaf7f02b52c5346ad9912dfb11743b664ef Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 15:56:15 +0300 Subject: [PATCH 09/22] refactor: validation before iteration --- .../Messages/NetSdrMessageHelper.cs | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/NetSdrClientApp/Messages/NetSdrMessageHelper.cs b/NetSdrClientApp/Messages/NetSdrMessageHelper.cs index 1fb0248..b36b469 100644 --- a/NetSdrClientApp/Messages/NetSdrMessageHelper.cs +++ b/NetSdrClientApp/Messages/NetSdrMessageHelper.cs @@ -7,7 +7,6 @@ namespace NetSdrClientApp.Messages { - //TODO: analyze possible use of [StructLayout] for better performance and readability public static class NetSdrMessageHelper { private const short _maxMessageLength = 8191; @@ -108,23 +107,28 @@ public static bool TranslateMessage(byte[] msg, out MsgTypes type, out ControlIt public static IEnumerable GetSamples(ushort sampleSize, byte[] body) { - sampleSize /= 8; //to bytes - if (sampleSize > 4) + int sampleSizeBytes = sampleSize / 8; //to bytes + if (sampleSize > 4) { - throw new ArgumentOutOfRangeException(); + throw new ArgumentOutOfRangeException(nameof(sampleSize), + "Sample size must be 32 bits (4 bytes) or less."); } + return GetSamplesInternal(sampleSizeBytes, body); + } + + private static IEnumerable GetSamplesInternal(int sampleSizeBytes, byte[] body) + { var bodyEnumerable = body as IEnumerable; - var prefixBytes = Enumerable.Range(0, 4 - sampleSize) - .Select(b => (byte)0); + var prefixBytes = Enumerable.Range(0, 4 - sampleSizeBytes).Select(b => (byte)0); - while (bodyEnumerable.Count() >= sampleSize) + while (bodyEnumerable.Count() >= sampleSizeBytes) { yield return BitConverter.ToInt32(bodyEnumerable - .Take(sampleSize) + .Take(sampleSizeBytes) .Concat(prefixBytes) .ToArray()); - bodyEnumerable = bodyEnumerable.Skip(sampleSize); + bodyEnumerable = bodyEnumerable.Skip(sampleSizeBytes); } } From 6ad98d2866caf6a35466c9d78689827330fc1f85 Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 16:15:21 +0300 Subject: [PATCH 10/22] chore: remove TODO --- NetSdrClientApp/NetSdrClient.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/NetSdrClientApp/NetSdrClient.cs b/NetSdrClientApp/NetSdrClient.cs index efb0076..b923d96 100644 --- a/NetSdrClientApp/NetSdrClient.cs +++ b/NetSdrClientApp/NetSdrClient.cs @@ -153,7 +153,6 @@ private async Task SendTcpRequest(byte[] msg) private void _tcpClient_MessageReceived(object? sender, byte[] e) { - //TODO: add Unsolicited messages handling here if (_responseTaskSource != null) { _responseTaskSource.SetResult(e); From a987abb8da3126e49833e2b2f4be0a31e2811875 Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 16:15:45 +0300 Subject: [PATCH 11/22] refactor: remove unused "ex" --- NetSdrClientApp/Networking/UdpClientWrapper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NetSdrClientApp/Networking/UdpClientWrapper.cs b/NetSdrClientApp/Networking/UdpClientWrapper.cs index 3300bd9..b2566ff 100644 --- a/NetSdrClientApp/Networking/UdpClientWrapper.cs +++ b/NetSdrClientApp/Networking/UdpClientWrapper.cs @@ -37,7 +37,7 @@ public async Task StartListeningAsync() Console.WriteLine($"Received from {result.RemoteEndPoint}"); } } - catch (OperationCanceledException ex) + catch (OperationCanceledException) { //empty } From 39e141356da91dd60855fdd995d5a8a5e1972b32 Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 16:16:45 +0300 Subject: [PATCH 12/22] refactor: use static method instead of memory allocation --- NetSdrClientApp/Networking/UdpClientWrapper.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/NetSdrClientApp/Networking/UdpClientWrapper.cs b/NetSdrClientApp/Networking/UdpClientWrapper.cs index b2566ff..a801bc6 100644 --- a/NetSdrClientApp/Networking/UdpClientWrapper.cs +++ b/NetSdrClientApp/Networking/UdpClientWrapper.cs @@ -72,8 +72,7 @@ public override int GetHashCode() { var payload = $"{nameof(UdpClientWrapper)}|{_localEndPoint.Address}|{_localEndPoint.Port}"; - using var md5 = MD5.Create(); - var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(payload)); + var hash = MD5.HashData(Encoding.UTF8.GetBytes(payload)); return BitConverter.ToInt32(hash, 0); } From 269c6042d1ebeeedbd6447a40ad63751be0588bf Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 16:19:00 +0300 Subject: [PATCH 13/22] refactor: add nullable & readonly --- NetSdrClientApp/Networking/TcpClientWrapper.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NetSdrClientApp/Networking/TcpClientWrapper.cs b/NetSdrClientApp/Networking/TcpClientWrapper.cs index ba300f0..9d77212 100644 --- a/NetSdrClientApp/Networking/TcpClientWrapper.cs +++ b/NetSdrClientApp/Networking/TcpClientWrapper.cs @@ -12,11 +12,11 @@ namespace NetSdrClientApp.Networking { public class TcpClientWrapper : ITcpClient { - private string _host; - private int _port; + private readonly string _host; + private readonly int _port; private TcpClient? _tcpClient; private NetworkStream? _stream; - private CancellationTokenSource _cts; + private CancellationTokenSource? _cts; public bool Connected => _tcpClient != null && _tcpClient.Connected && _stream != null; From 1b06074f7e7efa0d644dbbde681ff28cdd9e2ef0 Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 16:21:37 +0300 Subject: [PATCH 14/22] refactor: use Memory --- NetSdrClientApp/Networking/TcpClientWrapper.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NetSdrClientApp/Networking/TcpClientWrapper.cs b/NetSdrClientApp/Networking/TcpClientWrapper.cs index 9d77212..bf7c57e 100644 --- a/NetSdrClientApp/Networking/TcpClientWrapper.cs +++ b/NetSdrClientApp/Networking/TcpClientWrapper.cs @@ -77,7 +77,8 @@ public async Task SendMessageAsync(byte[] data) if (Connected && _stream != null && _stream.CanWrite) { Console.WriteLine($"Message sent: " + data.Select(b => Convert.ToString(b, toBase: 16)).Aggregate((l, r) => $"{l} {r}")); - await _stream.WriteAsync(data, 0, data.Length); + + await _stream.WriteAsync(data.AsMemory()); } else { From 70c8c6a33622f57021a5a7cdb3ab84e0a3591717 Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 16:27:40 +0300 Subject: [PATCH 15/22] refactor: use AsMemory() & remove unused ex --- NetSdrClientApp/Networking/TcpClientWrapper.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NetSdrClientApp/Networking/TcpClientWrapper.cs b/NetSdrClientApp/Networking/TcpClientWrapper.cs index bf7c57e..dd262a6 100644 --- a/NetSdrClientApp/Networking/TcpClientWrapper.cs +++ b/NetSdrClientApp/Networking/TcpClientWrapper.cs @@ -104,14 +104,14 @@ private async Task StartListeningAsync() { byte[] buffer = new byte[8194]; - int bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length, _cts.Token); + int bytesRead = await _stream.ReadAsync(buffer.AsMemory(), _cts.Token); if (bytesRead > 0) { MessageReceived?.Invoke(this, buffer.AsSpan(0, bytesRead).ToArray()); } } } - catch (OperationCanceledException ex) + catch (OperationCanceledException) { //empty } From 7e08c415384bde0082da38026da07819e460efc5 Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 16:33:44 +0300 Subject: [PATCH 16/22] test: use Assert.Multiple --- .../NetSdrMessageHelperTests.cs | 60 ++++++++++++------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/NetSdrClientAppTests/NetSdrMessageHelperTests.cs b/NetSdrClientAppTests/NetSdrMessageHelperTests.cs index 3250530..01bed4e 100644 --- a/NetSdrClientAppTests/NetSdrMessageHelperTests.cs +++ b/NetSdrClientAppTests/NetSdrMessageHelperTests.cs @@ -30,13 +30,17 @@ public void GetControlItemMessageTest() var actualCode = BitConverter.ToInt16(codeBytes.ToArray()); //Assert - Assert.That(headerBytes.Count(), Is.EqualTo(2)); - Assert.That(msg.Length, Is.EqualTo(actualLength)); - Assert.That(type, Is.EqualTo(actualType)); - - Assert.That(actualCode, Is.EqualTo((short)code)); - - Assert.That(parametersBytes.Count(), Is.EqualTo(parametersLength)); + var headerBytesArray = headerBytes.ToArray(); + var parametersBytesArray = parametersBytes.ToArray(); + + Assert.Multiple(() => + { + Assert.That(headerBytesArray, Has.Length.EqualTo(2)); + Assert.That(msg, Has.Length.EqualTo(actualLength)); + Assert.That(type, Is.EqualTo(actualType)); + Assert.That(actualCode, Is.EqualTo((short)code)); + Assert.That(parametersBytesArray, Has.Length.EqualTo(parametersLength)); + }); } [Test] @@ -57,11 +61,16 @@ public void GetDataItemMessageTest() var actualLength = num - ((int)actualType << 13); //Assert - Assert.That(headerBytes.Count(), Is.EqualTo(2)); - Assert.That(msg.Length, Is.EqualTo(actualLength)); - Assert.That(type, Is.EqualTo(actualType)); - - Assert.That(parametersBytes.Count(), Is.EqualTo(parametersLength)); + var headerBytesArray = headerBytes.ToArray(); + var parametersBytesArray = parametersBytes.ToArray(); + + Assert.Multiple(() => + { + Assert.That(headerBytesArray, Has.Length.EqualTo(2)); + Assert.That(msg, Has.Length.EqualTo(actualLength)); + Assert.That(type, Is.EqualTo(actualType)); + Assert.That(parametersBytesArray, Has.Length.EqualTo(parametersLength)); + }); } [Test] @@ -75,9 +84,12 @@ public void GetSamples_WithValid16BitData_ReturnsCorrectIntegers() var result = NetSdrMessageHelper.GetSamples(sampleSize, body).ToList(); // Assert - Assert.That(result, Has.Count.EqualTo(2)); - Assert.That(result[0], Is.EqualTo(1)); - Assert.That(result[1], Is.EqualTo(256)); + Assert.Multiple(() => + { + Assert.That(result, Has.Count.EqualTo(2)); + Assert.That(result[0], Is.EqualTo(1)); + Assert.That(result[1], Is.EqualTo(256)); + }); } [Test] @@ -106,10 +118,13 @@ public void TranslateMessage_WithValidData_ReturnsTrueAndCorrectBody() rawMessage, out var outType, out var outCode, out var seqNum, out var outBody); // Assert - Assert.That(success, Is.True); - Assert.That(outType, Is.EqualTo(type)); - Assert.That(outCode, Is.EqualTo(code)); - Assert.That(outBody, Is.EquivalentTo(dummyParams)); + Assert.Multiple(() => + { + Assert.That(success, Is.True); + Assert.That(outType, Is.EqualTo(type)); + Assert.That(outCode, Is.EqualTo(code)); + Assert.That(outBody, Is.EquivalentTo(dummyParams)); + }); } [Test] @@ -128,8 +143,11 @@ public void TranslateMessage_WithInvalidControlItemCode_ReturnsFalse() rawMessage, out var outType, out var outCode, out var seqNum, out var outBody); // Assert - Assert.That(success, Is.False); - Assert.That(outCode, Is.EqualTo(NetSdrMessageHelper.ControlItemCodes.None)); + Assert.Multiple(() => + { + Assert.That(success, Is.False); + Assert.That(outCode, Is.EqualTo(NetSdrMessageHelper.ControlItemCodes.None)); + }); } } } \ No newline at end of file From 334721e4fc5401d110c984a27ff983135d418ab8 Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 16:47:35 +0300 Subject: [PATCH 17/22] fix: typo --- NetSdrClientApp/Messages/NetSdrMessageHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NetSdrClientApp/Messages/NetSdrMessageHelper.cs b/NetSdrClientApp/Messages/NetSdrMessageHelper.cs index b36b469..00d55d3 100644 --- a/NetSdrClientApp/Messages/NetSdrMessageHelper.cs +++ b/NetSdrClientApp/Messages/NetSdrMessageHelper.cs @@ -108,7 +108,7 @@ public static bool TranslateMessage(byte[] msg, out MsgTypes type, out ControlIt public static IEnumerable GetSamples(ushort sampleSize, byte[] body) { int sampleSizeBytes = sampleSize / 8; //to bytes - if (sampleSize > 4) + if (sampleSizeBytes > 4) { throw new ArgumentOutOfRangeException(nameof(sampleSize), "Sample size must be 32 bits (4 bytes) or less."); From 1c35f29b6fa321aa5cae819f36ba66b6b1f8ec12 Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 17:11:19 +0300 Subject: [PATCH 18/22] test: ignore network wrappers in code coverage analysis --- NetSdrClientApp/Networking/TcpClientWrapper.cs | 2 ++ NetSdrClientApp/Networking/UdpClientWrapper.cs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/NetSdrClientApp/Networking/TcpClientWrapper.cs b/NetSdrClientApp/Networking/TcpClientWrapper.cs index dd262a6..112e3e8 100644 --- a/NetSdrClientApp/Networking/TcpClientWrapper.cs +++ b/NetSdrClientApp/Networking/TcpClientWrapper.cs @@ -7,9 +7,11 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using System.Diagnostics.CodeAnalysis; namespace NetSdrClientApp.Networking { + [ExcludeFromCodeCoverage] public class TcpClientWrapper : ITcpClient { private readonly string _host; diff --git a/NetSdrClientApp/Networking/UdpClientWrapper.cs b/NetSdrClientApp/Networking/UdpClientWrapper.cs index a801bc6..ac71a5c 100644 --- a/NetSdrClientApp/Networking/UdpClientWrapper.cs +++ b/NetSdrClientApp/Networking/UdpClientWrapper.cs @@ -5,9 +5,11 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using System.Diagnostics.CodeAnalysis; namespace NetSdrClientApp.Networking; +[ExcludeFromCodeCoverage] public class UdpClientWrapper : IUdpClient { private readonly IPEndPoint _localEndPoint; From ba040af3655e7ccde1b4dfe82e3279de1ff33a7e Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 17:12:51 +0300 Subject: [PATCH 19/22] fix: possible NullReferenceException --- NetSdrClientApp/Networking/TcpClientWrapper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NetSdrClientApp/Networking/TcpClientWrapper.cs b/NetSdrClientApp/Networking/TcpClientWrapper.cs index 112e3e8..ac716f2 100644 --- a/NetSdrClientApp/Networking/TcpClientWrapper.cs +++ b/NetSdrClientApp/Networking/TcpClientWrapper.cs @@ -102,7 +102,7 @@ private async Task StartListeningAsync() { Console.WriteLine($"Starting listening for incomming messages."); - while (!_cts.Token.IsCancellationRequested) + while (_cts != null && !_cts.Token.IsCancellationRequested) { byte[] buffer = new byte[8194]; From bd65a7c810b692d33e792077c6730b9be58f1385 Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 17:16:19 +0300 Subject: [PATCH 20/22] refactor: use HashCode.Combine instead of MD5 --- NetSdrClientApp/Networking/UdpClientWrapper.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/NetSdrClientApp/Networking/UdpClientWrapper.cs b/NetSdrClientApp/Networking/UdpClientWrapper.cs index ac71a5c..58989b9 100644 --- a/NetSdrClientApp/Networking/UdpClientWrapper.cs +++ b/NetSdrClientApp/Networking/UdpClientWrapper.cs @@ -1,8 +1,6 @@ using System; using System.Net; using System.Net.Sockets; -using System.Security.Cryptography; -using System.Text; using System.Threading; using System.Threading.Tasks; using System.Diagnostics.CodeAnalysis; @@ -72,10 +70,6 @@ public override bool Equals(object? obj) public override int GetHashCode() { - var payload = $"{nameof(UdpClientWrapper)}|{_localEndPoint.Address}|{_localEndPoint.Port}"; - - var hash = MD5.HashData(Encoding.UTF8.GetBytes(payload)); - - return BitConverter.ToInt32(hash, 0); + return HashCode.Combine(_localEndPoint.Address, _localEndPoint.Port); } } \ No newline at end of file From 739afdcd4f83719170ac148818ab1fbcaefab140 Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 17:28:57 +0300 Subject: [PATCH 21/22] test: exclude UdpTimedSender from coverage --- EchoTcpServer/Program.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/EchoTcpServer/Program.cs b/EchoTcpServer/Program.cs index e07088c..f2a93ee 100644 --- a/EchoTcpServer/Program.cs +++ b/EchoTcpServer/Program.cs @@ -130,6 +130,7 @@ public class UdpTimedSender : IDisposable private Timer? _timer; private bool _disposed = false; + [ExcludeFromCodeCoverage] public UdpTimedSender(string host, int port) { _host = host; From b58e23afca57a0d6c84897a0a309a7ce77f78520 Mon Sep 17 00:00:00 2001 From: SweetPumpkinPie Date: Mon, 18 May 2026 17:28:57 +0300 Subject: [PATCH 22/22] test: exclude UdpTimedSender from coverage --- EchoTcpServer/Program.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/EchoTcpServer/Program.cs b/EchoTcpServer/Program.cs index f2a93ee..549f3cb 100644 --- a/EchoTcpServer/Program.cs +++ b/EchoTcpServer/Program.cs @@ -122,6 +122,7 @@ public static async Task Main(string[] args) } +[ExcludeFromCodeCoverage] public class UdpTimedSender : IDisposable { private readonly string _host;