|
1 | | -using System; |
2 | | -using System.Net; |
| 1 | +using System.Net; |
3 | 2 | using System.Net.Sockets; |
4 | 3 | using System.Security.Cryptography; |
5 | 4 | using System.Text; |
6 | | -using System.Threading; |
7 | | -using System.Threading.Tasks; |
8 | 5 | using System.Diagnostics.CodeAnalysis; |
9 | 6 |
|
10 | | - |
11 | | -public class UdpClientWrapper : IUdpClient |
| 7 | +namespace NetSdrClientApp.Networking |
12 | 8 | { |
13 | | - private readonly IPEndPoint _localEndPoint; |
14 | | - private CancellationTokenSource? _cts; |
15 | | - private UdpClient? _udpClient; |
16 | | - |
17 | | - public event EventHandler<byte[]>? MessageReceived; |
18 | | - |
19 | | - public UdpClientWrapper(int port) |
| 9 | + public class UdpClientWrapper : IUdpClient, IDisposable |
20 | 10 | { |
21 | | - _localEndPoint = new IPEndPoint(IPAddress.Any, port); |
22 | | - } |
| 11 | + private readonly IPEndPoint _localEndPoint; |
| 12 | + private CancellationTokenSource? _cts; |
| 13 | + private UdpClient? _udpClient; |
| 14 | + private bool _disposed; |
23 | 15 |
|
24 | | - public async Task StartListeningAsync() |
25 | | - { |
26 | | - _cts = new CancellationTokenSource(); |
27 | | - Console.WriteLine("Start listening for UDP messages..."); |
| 16 | + public event EventHandler<byte[]>? MessageReceived; |
28 | 17 |
|
29 | | - try |
| 18 | + public UdpClientWrapper(int port) |
30 | 19 | { |
31 | | - _udpClient = new UdpClient(_localEndPoint); |
32 | | - while (!_cts.Token.IsCancellationRequested) |
33 | | - { |
34 | | - UdpReceiveResult result = await _udpClient.ReceiveAsync(_cts.Token); |
35 | | - MessageReceived?.Invoke(this, result.Buffer); |
| 20 | + _localEndPoint = new IPEndPoint(IPAddress.Any, port); |
| 21 | + } |
36 | 22 |
|
37 | | - Console.WriteLine($"Received from {result.RemoteEndPoint}"); |
| 23 | + [ExcludeFromCodeCoverage] |
| 24 | + public async Task StartListeningAsync() |
| 25 | + { |
| 26 | + _cts = new CancellationTokenSource(); |
| 27 | + Console.WriteLine("Start listening for UDP messages..."); |
| 28 | + |
| 29 | + try |
| 30 | + { |
| 31 | + _udpClient = new UdpClient(_localEndPoint); |
| 32 | + while (!_cts.Token.IsCancellationRequested) |
| 33 | + { |
| 34 | + UdpReceiveResult result = await _udpClient.ReceiveAsync(_cts.Token); |
| 35 | + MessageReceived?.Invoke(this, result.Buffer); |
| 36 | + Console.WriteLine($"Received from {result.RemoteEndPoint}"); |
| 37 | + } |
| 38 | + } |
| 39 | + catch (OperationCanceledException) |
| 40 | + { |
| 41 | + // Очікувана подія при зупинці |
| 42 | + } |
| 43 | + catch (Exception ex) |
| 44 | + { |
| 45 | + Console.WriteLine($"Error receiving message: {ex.Message}"); |
| 46 | + } |
| 47 | + finally |
| 48 | + { |
| 49 | + _cts?.Dispose(); // Dispose для _cts |
38 | 50 | } |
39 | 51 | } |
40 | | - catch (OperationCanceledException ex) |
| 52 | + |
| 53 | + [ExcludeFromCodeCoverage] |
| 54 | + public void StopListening() |
41 | 55 | { |
42 | | - //empty |
| 56 | + SafeStop("Stopped listening for UDP messages."); |
43 | 57 | } |
44 | | - catch (Exception ex) |
| 58 | + |
| 59 | + [ExcludeFromCodeCoverage] |
| 60 | + public void Exit() |
45 | 61 | { |
46 | | - Console.WriteLine($"Error receiving message: {ex.Message}"); |
| 62 | + SafeStop("Stopped listening for UDP messages."); |
47 | 63 | } |
48 | | - } |
49 | 64 |
|
50 | | - [ExcludeFromCodeCoverage] |
51 | | - public void StopListening() |
52 | | - { |
53 | | - SafeStop("Stopped listening for UDP messages."); |
54 | | - } |
55 | | - |
56 | | - [ExcludeFromCodeCoverage] |
57 | | - public void Exit() |
58 | | - { |
59 | | - SafeStop("Stopped listening for UDP messages."); |
60 | | - } |
61 | | - |
62 | | - [ExcludeFromCodeCoverage] |
63 | | - private void SafeStop(string message) |
64 | | - { |
65 | | - try |
| 65 | + [ExcludeFromCodeCoverage] |
| 66 | + private void SafeStop(string message) |
66 | 67 | { |
67 | | - _cts?.Cancel(); |
68 | | - _udpClient?.Close(); |
69 | | - Console.WriteLine(message); |
| 68 | + try |
| 69 | + { |
| 70 | + _cts?.Cancel(); |
| 71 | + _udpClient?.Close(); |
| 72 | + Console.WriteLine(message); |
| 73 | + } |
| 74 | + catch (Exception ex) |
| 75 | + { |
| 76 | + Console.WriteLine($"Error while stopping: {ex.Message}"); |
| 77 | + } |
70 | 78 | } |
71 | | - catch (Exception ex) |
| 79 | + |
| 80 | + public override int GetHashCode() |
72 | 81 | { |
73 | | - Console.WriteLine($"Error while stopping: {ex.Message}"); |
| 82 | + var payload = $"{nameof(UdpClientWrapper)}|{_localEndPoint.Address}|{_localEndPoint.Port}"; |
| 83 | + using var sha256 = SHA256.Create(); |
| 84 | + var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(payload)); |
| 85 | + return BitConverter.ToInt32(hash, 0); |
74 | 86 | } |
75 | | - } |
76 | 87 |
|
| 88 | + public override bool Equals(object? obj) |
| 89 | + { |
| 90 | + if (obj is not UdpClientWrapper other) |
| 91 | + return false; |
77 | 92 |
|
78 | | - public override int GetHashCode() |
79 | | - { |
80 | | - var payload = $"{nameof(UdpClientWrapper)}|{_localEndPoint.Address}|{_localEndPoint.Port}"; |
| 93 | + return _localEndPoint.Address.Equals(other._localEndPoint.Address) |
| 94 | + && _localEndPoint.Port == other._localEndPoint.Port; |
| 95 | + } |
81 | 96 |
|
82 | | - using var md5 = MD5.Create(); |
83 | | - var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(payload)); |
| 97 | + public void Dispose() |
| 98 | + { |
| 99 | + if (_disposed) return; |
84 | 100 |
|
85 | | - return BitConverter.ToInt32(hash, 0); |
| 101 | + _cts?.Cancel(); |
| 102 | + _cts?.Dispose(); |
| 103 | + _udpClient?.Dispose(); |
| 104 | + _disposed = true; |
| 105 | + GC.SuppressFinalize(this); |
| 106 | + } |
86 | 107 | } |
87 | 108 | } |
0 commit comments