soundbeam – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | using System; |
2 | using System.Net; |
||
3 | using System.Net.Sockets; |
||
4 | using System.Threading; |
||
5 | using System.Threading.Tasks; |
||
6 | |||
7 | namespace SoundBeam |
||
8 | { |
||
9 | public class TcpServer : IDisposable |
||
10 | { |
||
11 | public IPAddress ListenIpAddress { get; } |
||
12 | |||
13 | public int ListenPort { get; } |
||
14 | |||
15 | private TcpListener _listener; |
||
16 | |||
17 | private Task _processTcpClientsTask; |
||
18 | |||
19 | private CancellationTokenSource _serverCancellationTokenSource; |
||
20 | |||
21 | public TcpServer(string address, int port) |
||
22 | { |
||
23 | if (!IPAddress.TryParse(address, out var listenIpAddress)) |
||
24 | { |
||
25 | throw new ArgumentException(); |
||
26 | } |
||
27 | |||
28 | ListenIpAddress = listenIpAddress; |
||
29 | ListenPort = port; |
||
30 | } |
||
31 | |||
32 | public void Dispose() |
||
33 | { |
||
34 | Stop(); |
||
35 | |||
36 | _serverCancellationTokenSource?.Dispose(); |
||
37 | _serverCancellationTokenSource = null; |
||
38 | } |
||
39 | |||
40 | public event EventHandler<TcpClientConnectedEventArgs> ClientConnected; |
||
41 | |||
42 | public async Task ProcessTcpClients(CancellationToken token) |
||
43 | { |
||
44 | _listener.Start(); |
||
45 | |||
46 | do |
||
47 | { |
||
48 | try |
||
49 | { |
||
50 | var client = await Task.Run(() => _listener.AcceptTcpClientAsync(), token); |
||
51 | |||
52 | if (client == null) |
||
53 | { |
||
54 | continue; |
||
55 | } |
||
56 | |||
57 | ClientConnected?.Invoke(this, new TcpClientConnectedEventArgs(client)); |
||
58 | } |
||
59 | catch (OperationCanceledException) |
||
60 | { |
||
61 | // Going down and we don't care. |
||
62 | return; |
||
63 | } |
||
64 | catch (Exception ex) |
||
65 | { |
||
66 | // |
||
67 | } |
||
68 | } while (!token.IsCancellationRequested); |
||
69 | } |
||
70 | |||
71 | public void Start() |
||
72 | { |
||
73 | _listener = new TcpListener(ListenIpAddress, ListenPort); |
||
74 | |||
75 | _serverCancellationTokenSource = new CancellationTokenSource(); |
||
76 | |||
77 | #pragma warning disable 4014 // Processing TCP clients will run asynchronously. |
||
78 | _processTcpClientsTask = ProcessTcpClients(_serverCancellationTokenSource.Token); |
||
79 | #pragma warning restore 4014 |
||
80 | } |
||
81 | |||
82 | public void Stop() |
||
83 | { |
||
84 | _serverCancellationTokenSource?.Cancel(); |
||
85 | _processTcpClientsTask?.Wait(); |
||
86 | |||
87 | _listener?.Stop(); |
||
88 | } |
||
89 | } |
||
90 | } |