123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- 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<TcpClient> _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<bool> taskCompletionSource = new();
- Task.Factory.StartNew(() => WaitForConnection(taskCompletionSource), TaskCreationOptions.LongRunning);
- if (!taskCompletionSource.Task.Result)
- return false;
- _bOpen = true;
- return true;
- }
- }
- async Task WaitForConnection(TaskCompletionSource<bool>? taskCompletionSource = null)
- {
- if (_bExit)
- return;
- Task<System.Net.Sockets.TcpClient>? 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();
- }
- }
|