IOTcpServer.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. namespace UniversalNetFrame451.IO;
  2. internal class IOTcpServer : BaseFilter, ITcpServer
  3. {
  4. #region Internal Variables
  5. public string Name { get; set; }
  6. private volatile bool _bInitialize = false;
  7. private volatile bool _bOpen = false;
  8. private volatile bool _bExit = false;
  9. private bool _noDelay = false;
  10. private int _receiveBufferSize = 0;
  11. private TcpListener _tcpListener = null;
  12. private readonly HashSet<TcpClient> _clients = [];
  13. #endregion
  14. bool ITcpServer.Initialize(string name)
  15. {
  16. lock (this)
  17. {
  18. if (_bInitialize)
  19. return false;
  20. Name = name;
  21. _bInitialize = true;
  22. return true;
  23. }
  24. }
  25. bool ITcpServer.Open(string ip, ushort port, bool noDelay, int receiveBufferSize)
  26. {
  27. lock (this)
  28. {
  29. if (!_bInitialize)
  30. return false;
  31. if (_bOpen)
  32. return false;
  33. _bExit = false;
  34. IPAddress address = IPAddress.Any;
  35. if (!string.IsNullOrWhiteSpace(ip))
  36. if (!IPAddress.TryParse(ip, out address))
  37. return false;
  38. TcpListener tcpListener = null;
  39. try
  40. {
  41. tcpListener = new(address, port);
  42. tcpListener.Start();
  43. }
  44. catch
  45. {
  46. return false;
  47. }
  48. _noDelay = noDelay;
  49. _receiveBufferSize = receiveBufferSize;
  50. _tcpListener = tcpListener;
  51. TaskCompletionSource<bool> taskCompletionSource = new();
  52. Task.Factory.StartNew(() => WaitForConnection(taskCompletionSource), TaskCreationOptions.LongRunning);
  53. if (!taskCompletionSource.Task.Result)
  54. return false;
  55. _bOpen = true;
  56. return true;
  57. }
  58. }
  59. async Task WaitForConnection(TaskCompletionSource<bool> taskCompletionSource = null)
  60. {
  61. if (_bExit)
  62. return;
  63. Task<System.Net.Sockets.TcpClient> taskAcceptTcpClientAsync = default;
  64. try
  65. {
  66. taskAcceptTcpClientAsync = _tcpListener!.AcceptTcpClientAsync();
  67. taskCompletionSource.SetResult(true);
  68. }
  69. catch
  70. {
  71. try { taskCompletionSource.SetResult(false); } catch { }
  72. }
  73. try
  74. {
  75. System.Net.Sockets.TcpClient tcpClient = await taskAcceptTcpClientAsync!;
  76. tcpClient.NoDelay = _noDelay;
  77. tcpClient.SendTimeout = 200;
  78. tcpClient.ReceiveTimeout = 200;
  79. if (_bExit)
  80. {
  81. tcpClient.Close();
  82. return;
  83. }
  84. NetworkStream networkStream = tcpClient.GetStream();
  85. if (tcpClient.Client.LocalEndPoint is not IPEndPoint || tcpClient.Client.RemoteEndPoint is not IPEndPoint)
  86. return;
  87. TcpConnection connection = new(
  88. (IPEndPoint)tcpClient.Client.LocalEndPoint!,
  89. (IPEndPoint)tcpClient.Client.RemoteEndPoint!,
  90. tcpClient);
  91. lock (_clients)
  92. {
  93. _clients.Add(tcpClient);
  94. }
  95. _ = Task.Factory.StartNew(async () => { try { await WaitForConnection(); } catch (Exception) { } }, TaskCreationOptions.LongRunning);
  96. try
  97. {
  98. try { PrevConnector.Connected(connection); } catch { }
  99. for (byte[] buffer = new byte[_receiveBufferSize]; ;)
  100. {
  101. int bytesRead = 0;
  102. DateTime receiveTime;
  103. try
  104. {
  105. bytesRead = await networkStream.ReadAsync(buffer, 0, _receiveBufferSize);
  106. receiveTime = DateTime.Now;
  107. }
  108. catch
  109. {
  110. break;
  111. }
  112. if (bytesRead <= 0)
  113. {
  114. lock (_clients)
  115. if (_clients.Contains(tcpClient))
  116. _clients.Remove(tcpClient);
  117. break;
  118. }
  119. byte[] cache = new byte[bytesRead];
  120. Array.Copy(buffer, cache, bytesRead);
  121. try { this.PrevReceiver.Receive(new(cache, connection, receiveTime)); } catch { }
  122. }
  123. try
  124. {
  125. tcpClient.Close();
  126. PrevConnector.Disconnected(connection);
  127. }
  128. catch { }
  129. }
  130. catch { }
  131. }
  132. catch { }
  133. }
  134. public override bool Send(Data data)
  135. {
  136. if (!_bInitialize)
  137. return false;
  138. if (!_bOpen)
  139. return false;
  140. if (data.Connection is not TcpConnection tcp)
  141. return false;
  142. if (tcp.TcpClient is null)
  143. return false;
  144. try
  145. {
  146. if (!tcp.TcpClient!.Connected)
  147. return false;
  148. if (data.RawData == null || data.RawData.Length == 0)
  149. return false;
  150. NetworkStream networkStream = tcp.TcpClient.GetStream();
  151. networkStream.Write([.. data.RawData], 0, data.RawData.Length);
  152. networkStream.Flush();
  153. data.DateTime = DateTime.Now;
  154. }
  155. catch
  156. {
  157. return false;
  158. }
  159. return true;
  160. }
  161. bool ITcpServer.Close()
  162. {
  163. lock (this)
  164. {
  165. if (!_bInitialize)
  166. return false;
  167. if (!_bOpen)
  168. return true;
  169. _bExit = true;
  170. try { _tcpListener.Stop(); } catch { }
  171. lock (_clients)
  172. {
  173. foreach (System.Net.Sockets.TcpClient tcpClient in _clients)
  174. tcpClient.Close();
  175. _clients.Clear();
  176. }
  177. _bOpen = false;
  178. return true;
  179. }
  180. }
  181. public void Dispose()
  182. {
  183. (this as ITcpServer).Close();
  184. }
  185. }