TcppServer.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. using Azylee.Core.ThreadUtils.SleepUtils;
  2. using Azylee.Core.WindowsUtils.ConsoleUtils;
  3. using Azylee.Jsons;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Net;
  8. using System.Net.Sockets;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. namespace Azylee.YeahWeb.SocketUtils.TcpUtils
  12. {
  13. /// <summary>
  14. /// Tcp 服务工具
  15. /// </summary>
  16. public class TcppServer
  17. {
  18. const int ReceiveBufferSize = 1024;
  19. private List<byte> ReceiveByte = new List<byte>();
  20. private int _Port = 52801;
  21. TcpListener Listener = null;
  22. Action<TcpClientInfo> OnConnectAction = null;
  23. Action<TcpClientInfo> OnDisconnectAction = null;
  24. Action<TcpClientInfo, TcpDataModel> OnReceiveAction = null;
  25. public TcpClientManager TcpClientManager = new TcpClientManager();
  26. /// <summary>
  27. /// 构造函数
  28. /// </summary>
  29. /// <param name="port">端口号</param>
  30. /// <param name="onConnect">连接动作</param>
  31. /// <param name="onDisconnect">断开动作</param>
  32. /// <param name="onReceive">接收消息</param>
  33. public TcppServer(int port, Action<TcpClientInfo> onConnect, Action<TcpClientInfo> onDisconnect, Action<TcpClientInfo, TcpDataModel> onReceive)
  34. {
  35. _Port = port;
  36. OnConnectAction = onConnect;
  37. OnDisconnectAction = onDisconnect;
  38. OnReceiveAction = onReceive;
  39. }
  40. #region 启动和停止服务
  41. /// <summary>
  42. /// 启动服务
  43. /// </summary>
  44. public void Start()
  45. {
  46. this.Listener = new TcpListener(IPAddress.Any, _Port);
  47. this.Listener.Start();
  48. this.Listener.BeginAcceptTcpClient(new AsyncCallback(acceptCallback), this.Listener);
  49. }
  50. /// <summary>
  51. /// 停止服务
  52. /// </summary>
  53. public void Stop()
  54. {
  55. foreach (var client in TcpClientManager.GetAll())
  56. {
  57. client?.Client?.Close();
  58. }
  59. Listener?.Stop();
  60. }
  61. #endregion
  62. #region 连接后的读写操作
  63. /// <summary>
  64. /// 发送数据
  65. /// </summary>
  66. /// <param name="host">主机地址</param>
  67. /// <param name="model">数据模型</param>
  68. public bool Write(string host, TcpDataModel model)
  69. {
  70. var dictionary = TcpClientManager.GetInfoByHost(host);
  71. if (dictionary != null && dictionary.Client != null)
  72. {
  73. if (dictionary.Client.Connected)
  74. {
  75. TcpClientManager.UpdateUploadFlowCount(host, model.Data.Length);
  76. bool flag = TcpStreamHelper.Write(dictionary.Client, model);
  77. return flag;
  78. }
  79. }
  80. return false;
  81. }
  82. private void acceptCallback(IAsyncResult state)
  83. {
  84. try
  85. {
  86. TcpListener lstn = (TcpListener)state.AsyncState;
  87. TcpClient client = lstn.EndAcceptTcpClient(state);
  88. string host = client.Client.RemoteEndPoint.ToString();
  89. TcpClientManager.AddOrUpdate(host, client);
  90. ConnectTask(host, client);
  91. lstn.BeginAcceptTcpClient(new AsyncCallback(acceptCallback), lstn);
  92. }
  93. catch { }
  94. }
  95. private void ConnectTask(string host, TcpClient client)
  96. {
  97. TcpClientInfo clientInfo = TcpClientManager.GetInfoByHost(host);
  98. //发送心跳
  99. Task.Factory.StartNew(() =>
  100. {
  101. while (client.Connected)
  102. {
  103. TcpDataModel model = new TcpDataModel(int.MaxValue);
  104. TcpStreamHelper.Write(client, model);
  105. Sleep.S(5);
  106. //if (DateTime.Now.AddSeconds(-10) > HeartbeatTime)
  107. // client.Close();
  108. Sleep.S(5);
  109. }
  110. });
  111. //接收消息
  112. Task.Factory.StartNew(() =>
  113. {
  114. OnConnectAction?.Invoke(clientInfo);//委托:已连接
  115. while (client.Connected)
  116. {
  117. try
  118. {
  119. TcpDataModel model = TcpStreamHelper.Read(client);
  120. if (model != null)
  121. {
  122. if (model.Type == int.MaxValue)
  123. {
  124. //过滤心跳,并记录心跳时间
  125. TcpClientManager.UpdateHeartbeatTime(host);
  126. }
  127. else
  128. {
  129. TcpClientManager.UpdateDownloadFlowCount(host, model.Data.Length);
  130. OnReceiveAction(clientInfo, model);//委托:接收消息
  131. }
  132. }
  133. }
  134. catch { }
  135. //Sleep.S(1);
  136. }
  137. client.Close();
  138. TcpClientManager.RemoveByHost(host);
  139. OnDisconnectAction?.Invoke(clientInfo);//委托:断开连接
  140. });
  141. }
  142. #endregion
  143. }
  144. }