soundbeam – Rev 1

Subversion Repositories:
Rev:
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;

namespace SoundBeam
{
    public class TcpServer : IDisposable
    {
        public IPAddress ListenIpAddress { get; }

        public int ListenPort { get; }

        private TcpListener _listener;

        private Task _processTcpClientsTask;

        private CancellationTokenSource _serverCancellationTokenSource;

        public TcpServer(string address, int port)
        {
            if (!IPAddress.TryParse(address, out var listenIpAddress))
            {
                throw new ArgumentException();
            }

            ListenIpAddress = listenIpAddress;
            ListenPort = port;
        }

        public void Dispose()
        {
            Stop();

            _serverCancellationTokenSource?.Dispose();
            _serverCancellationTokenSource = null;
        }

        public event EventHandler<TcpClientConnectedEventArgs> ClientConnected;

        public async Task ProcessTcpClients(CancellationToken token)
        {
            _listener.Start();

            do
            {
                try
                {
                    var client = await Task.Run(() => _listener.AcceptTcpClientAsync(), token);

                    if (client == null)
                    {
                        continue;
                    }

                    ClientConnected?.Invoke(this, new TcpClientConnectedEventArgs(client));
                }
                catch (OperationCanceledException)
                {
                    // Going down and we don't care.
                    return;
                }
                catch (Exception ex)
                {
                    //
                }
            } while (!token.IsCancellationRequested);
        }

        public void Start()
        {
            _listener = new TcpListener(ListenIpAddress, ListenPort);

            _serverCancellationTokenSource = new CancellationTokenSource();

            #pragma warning disable 4014 // Processing TCP clients will run asynchronously.
            _processTcpClientsTask = ProcessTcpClients(_serverCancellationTokenSource.Token);
            #pragma warning restore 4014
        }

        public void Stop()
        {
            _serverCancellationTokenSource?.Cancel();
            _processTcpClientsTask?.Wait();

            _listener?.Stop();
        }
    }
}

Generated by GNU Enscript 1.6.5.90.