namespace Universal.IO; internal class IOTcpServer : BaseFilter, ITcpServer { #region Internal Variables public string? Name { get; set; } private volatile bool _bInitialize = false; private volatile bool _bOpen = false; private volatile bool _bExit = false; private bool _noDelay = false; private int _receiveBufferSize = 0; private TcpListener? _tcpListener = null; private readonly HashSet _clients = []; #endregion bool ITcpServer.Initialize(string name) { lock (this) { if (_bInitialize) return false; Name = name; _bInitialize = true; return true; } } bool ITcpServer.Open(string ip, ushort port, bool noDelay, int receiveBufferSize) { lock (this) { if (!_bInitialize) return false; if (_bOpen) return false; _bExit = false; IPAddress? address = IPAddress.Any; if (!string.IsNullOrWhiteSpace(ip)) if (!IPAddress.TryParse(ip, out address)) return false; TcpListener? tcpListener = null; try { tcpListener = new(address, port); tcpListener.Start(); } catch { return false; } _noDelay = noDelay; _receiveBufferSize = receiveBufferSize; _tcpListener = tcpListener; TaskCompletionSource taskCompletionSource = new(); Task.Factory.StartNew(() => WaitForConnection(taskCompletionSource), TaskCreationOptions.LongRunning); if (!taskCompletionSource.Task.Result) return false; _bOpen = true; return true; } } async Task WaitForConnection(TaskCompletionSource? taskCompletionSource = null) { if (_bExit) return; Task? taskAcceptTcpClientAsync = default; try { taskAcceptTcpClientAsync = _tcpListener!.AcceptTcpClientAsync(); taskCompletionSource?.SetResult(true); } catch { try { taskCompletionSource?.SetResult(false); } catch { } } try { System.Net.Sockets.TcpClient tcpClient = await taskAcceptTcpClientAsync!; tcpClient.NoDelay = _noDelay; if (_bExit) { tcpClient.Close(); return; } NetworkStream networkStream = tcpClient.GetStream(); if (tcpClient.Client.LocalEndPoint is not IPEndPoint || tcpClient.Client.RemoteEndPoint is not IPEndPoint) return; TcpConnection connection = new( (IPEndPoint)tcpClient.Client.LocalEndPoint!, (IPEndPoint)tcpClient.Client.RemoteEndPoint!, tcpClient); lock (_clients) _clients.Add(tcpClient); _ = Task.Factory.StartNew(async () => { try { await WaitForConnection(); } catch (Exception) { } }, TaskCreationOptions.LongRunning); try { try { PrevConnector?.Connected(connection); } catch { } for (byte[] buffer = new byte[_receiveBufferSize]; ;) { int bytesRead = 0; DateTime receiveTime; try { bytesRead = await networkStream.ReadAsync(buffer.AsMemory(0, _receiveBufferSize)); receiveTime = DateTime.Now; } catch { break; } if (bytesRead <= 0) { lock (_clients) _clients.Remove(tcpClient); break; } byte[] cache = new byte[bytesRead]; Array.Copy(buffer, cache, bytesRead); try { this.PrevReceiver?.Receive(new(cache, connection, receiveTime)); } catch { } } try { tcpClient.Close(); PrevConnector?.Disconnected(connection); } catch { } } catch { } } catch { } } public override bool Send(Data data) { if (!_bInitialize) return false; if (!_bOpen) return false; if (data.Connection is not TcpConnection tcp) return false; if (tcp.TcpClient is null) return false; try { if (!tcp.TcpClient!.Connected) return false; if (data.RawData == null || data.RawData.Length == 0) return false; NetworkStream networkStream = tcp.TcpClient.GetStream(); networkStream.Write([.. data.RawData], 0, data.RawData.Length); networkStream.Flush(); data.DateTime = DateTime.Now; } catch { return false; } return true; } bool ITcpServer.Close() { lock (this) { if (!_bInitialize) return false; if (!_bOpen) return true; _bExit = true; try { _tcpListener?.Stop(); } catch { } lock (_clients) { foreach (System.Net.Sockets.TcpClient tcpClient in _clients) tcpClient.Close(); _clients.Clear(); } _bOpen = false; return true; } } public void Dispose() { (this as ITcpServer).Close(); } }