TcppClient.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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.Sockets;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. namespace Azylee.YeahWeb.SocketUtils.TcpUtils
  11. {
  12. public class TcppClient
  13. {
  14. const int ReceiveBufferSize = 1024;
  15. private string _IP = "";
  16. private int _Port = 52801;
  17. private TcpClient Client = null;
  18. private NetworkStream networkStream = null;
  19. Action OnConnectAction = null;
  20. Action OnDisconnectAction = null;
  21. Action<TcpDataModel> OnReceiveAction = null;
  22. /// <summary>
  23. /// 构造函数
  24. /// </summary>
  25. /// <param name="ip"></param>
  26. /// <param name="port"></param>
  27. /// <param name="onConnect">连接动作</param>
  28. /// <param name="onDisconnect">断开动作</param>
  29. /// <param name="onReceive">接收消息</param>
  30. public TcppClient(string ip, int port, Action onConnect, Action onDisconnect, Action<TcpDataModel> onReceive)
  31. {
  32. this._IP = ip;
  33. this._Port = port;
  34. OnConnectAction = onConnect;
  35. OnDisconnectAction = onDisconnect;
  36. OnReceiveAction = onReceive;
  37. }
  38. #region 连接和关闭连接
  39. /// <summary>
  40. /// 连接到TcpServer(重连)
  41. /// </summary>
  42. public bool Connect()
  43. {
  44. try
  45. {
  46. if (this.Client == null || !this.Client.Connected)
  47. {
  48. this.Client = new TcpClient();
  49. //this.Read();
  50. IAsyncResult ar = this.Client.BeginConnect(this._IP, this._Port, acceptCallback, this.Client);
  51. bool isConnect = ar.AsyncWaitHandle.WaitOne(1000);
  52. if (isConnect) return true;
  53. }
  54. }
  55. catch { }
  56. return false;
  57. }
  58. /// <summary>
  59. /// 关闭连接
  60. /// </summary>
  61. public void Disconnect()
  62. {
  63. networkStream?.Close();
  64. Client?.Close();
  65. }
  66. #endregion
  67. #region 连接后的读写操作
  68. /// <summary>
  69. /// 发送数据
  70. /// </summary>
  71. /// <param name="model">数据模型</param>
  72. public bool Write(TcpDataModel model)
  73. {
  74. bool flag = false;
  75. if (this.Client != null && this.Client.Connected)
  76. {
  77. flag = TcpStreamHelper.Write(Client, model);
  78. }
  79. return flag;
  80. }
  81. /// <summary>
  82. /// 发送数据
  83. /// </summary>
  84. /// <param name="type">类型</param>
  85. /// <param name="data">数据</param>
  86. public bool Write(int type, byte[] data)
  87. {
  88. return Write(new TcpDataModel() { Type = type, Data = data });
  89. }
  90. /// <summary>
  91. /// 发送数据
  92. /// </summary>
  93. /// <param name="type">类型</param>
  94. /// <param name="s">字符串</param>
  95. public bool Write(int type, string s)
  96. {
  97. return Write(new TcpDataModel() { Type = type, Data = Json.Object2Byte(s) });
  98. }
  99. /// <summary>
  100. /// 接受数据
  101. /// </summary>
  102. private void acceptCallback(IAsyncResult state)
  103. {
  104. try
  105. {
  106. this.Client = (TcpClient)state.AsyncState;
  107. this.Client.EndConnect(state);
  108. // c# 系统检测到在一个调用中尝试使用指针参数时的无效指针地址 怎么解决
  109. // 用管理身份运行cmd,执行 netsh winsock reset 重启问题解决
  110. //string host = this.Client.Client.RemoteEndPoint.ToString();
  111. ConnectTask(Client);
  112. }
  113. catch (Exception ex) { }
  114. }
  115. private void ConnectTask(TcpClient client)
  116. {
  117. Task.Factory.StartNew(() =>
  118. {
  119. OnConnectAction?.Invoke();//委托:已连接
  120. while (client.Connected)
  121. {
  122. try
  123. {
  124. TcpDataModel model = TcpStreamHelper.Read(client);
  125. if (model != null)
  126. {
  127. if (model.Type == int.MaxValue)
  128. {
  129. //返回心跳
  130. Write(new TcpDataModel() { Type = int.MaxValue });
  131. }
  132. else
  133. {
  134. OnReceiveAction?.Invoke(model);//委托:接收消息
  135. }
  136. }
  137. }
  138. catch { }
  139. //Sleep.S(1);
  140. }
  141. client.Close();
  142. OnDisconnectAction?.Invoke();//委托:断开连接
  143. });
  144. //lstn.BeginAcceptTcpClient(new AsyncCallback(acceptCallback), lstn);
  145. }
  146. #endregion
  147. }
  148. }