/// /// IP-aдрес сервреа по-умолчанию /// Очевидный localhost /// private static IPAddress _defaultIPAddress = IPAddress.Parse("127.0.0.1"); /// /// Порт сервера по-умлочанию /// private static int _defaultPort = 9000; /// /// Конечная точка сервреа по-умлочанию /// private static IPEndPoint _defaultEndPoint = new IPEndPoint(_defaultIPAddress, _defaultPort); #endregion Default #region Private vars private TcpListener _listener = null; private bool _isStoped = false; private bool _isPurgingStoped = false; private Task _listeningTask = null; private Task _purgingTask = null; private ConcurrentDictionary> _sessions = null;//сессии сервера private object locker = new object(); //объект синхронизации потоков private DateTime _startTime; private CancellationToken cancellationToken; #endregion Private vars #region Props public int ConnectedSessionCount => this._sessions.Where(kv => !kv.Value.IsStoped).Count(); public TimeSpan UpTime => DateTime.Now - _startTime; public bool IsRuning => !_isStoped; #endregion Props #region ctors public TcpServer() : this(_defaultEndPoint) { } public TcpServer(int port) : this(new IPEndPoint(_defaultIPAddress, port)) { } public TcpServer(IPAddress address) : this(new IPEndPoint(address, _defaultPort)) { } public TcpServer(IPAddress address, int port) : this(new IPEndPoint(address, port)) { } public TcpServer(IPEndPoint endPoint) { Init(endPoint); } #endregion ctors #region Public methods public void Start(CancellationToken cancellationToken) { this.cancellationToken = cancellationToken; if(_listener != null) { _startTime = DateTime.Now; _sessions = new ConcurrentDictionary>(); _listener.Start(); _listeningTask = new Task(ServerListeningTask); _listeningTask.Start(); //Создаем nfcr очистки сессий _purgingTask = new Task(ServerPurgingTask); _purgingTask.Start(); } } public void Stop() { if(_listener != null || cancellationToken.IsCancellationRequested) { try { _isStoped = true; _listener.Stop(); _listeningTask.Wait(); _listeningTask = null; _purgingTask.Wait(); _purgingTask = null; _listener = null; StopAllClientSessions(); } catch { } } } #endregion Public methods #region Private methods private void Init(IPEndPoint endPoint) { try { _listener = new TcpListener(endPoint); } catch(Exception ex) { _listener = null; } } private void ServerListeningTask() { Socket clientSocket = null; TcpSession clientSession = null; while(!_isStoped || !this.cancellationToken.IsCancellationRequested) { try { clientSocket = _listener.AcceptSocket(); clientSession = new TcpSession(clientSocket); lock(locker) { _sessions.TryAdd(clientSession.ID, clientSession); } clientSession.StartSession(this.cancellationToken); } catch(SocketException ex) { _isStoped = true; } } } private void ServerPurgingTask() { while(!_isPurgingStoped || !cancellationToken.IsCancellationRequested) { var disconnected = _sessions.Where(s => s.Value.IsStoped == true); lock(locker) { foreach(var s in disconnected) { _sessions.TryRemove(s.Key, out var temp); } } disconnected = null; Thread.Sleep(1000); } } private void StopAllClientSessions() { foreach(var kv in _sessions) kv.Value.StopSession(); } #endregion Private methods