TcpSerializer.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. using AwInitilizer.Interface;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Linq;
  6. using System.Net;
  7. using System.Net.Sockets;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. namespace AwInitilizer.Assist
  11. {
  12. public class TcpSerializer : Interface.ISerialPort
  13. {
  14. public event EventHandler<byte[]> OnDataReceived;
  15. public event PropertyChangedEventHandler PropertyChanged;
  16. public string IP { get; private set; }
  17. private ConnectStatus _ConnectStatus = ConnectStatus.Cleared;
  18. public ConnectStatus ConnectStatus
  19. {
  20. get => _ConnectStatus;
  21. set
  22. {
  23. if (_ConnectStatus != value)
  24. {
  25. _ConnectStatus = value;
  26. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ConnectStatus"));
  27. }
  28. }
  29. }
  30. private IPAddress iPAddress;
  31. private IPEndPoint iPEndPoint;
  32. private Socket tcpSocket;
  33. public TcpSerializer(string ip = "192.168.1.10",int port = 8234)
  34. {
  35. IP = ip;
  36. iPAddress = IPAddress.Parse(ip);
  37. iPEndPoint = new IPEndPoint(iPAddress, port);
  38. }
  39. public async Task OpenAsync()
  40. {
  41. await Conenct();
  42. }
  43. public void Open()
  44. {
  45. _ = Conenct();
  46. }
  47. public void Close()
  48. {
  49. ConnectStatus = ConnectStatus.DisConnected;
  50. try
  51. {
  52. tcpSocket?.Close();
  53. tcpSocket?.Dispose();
  54. }
  55. catch
  56. {
  57. }
  58. }
  59. public void WriteData(byte[] msg)
  60. {
  61. if (ConnectStatus != ConnectStatus.Connected)
  62. return;
  63. tcpSocket.Send(msg);
  64. }
  65. private async Task Conenct()
  66. {
  67. ConnectStatus = ConnectStatus.Connecting;
  68. tcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  69. tcpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
  70. var connectTask = tcpSocket.ConnectAsync(iPEndPoint);
  71. //var asyncResult = tcpSocket.BeginConnect(iPEndPoint, OnTcpConnectComplete, null);
  72. //await Task.Delay(2 * 1000);
  73. await Task.WhenAny(connectTask, Task.Delay(2 * 1000));
  74. if (tcpSocket.Connected)
  75. {
  76. ConnectStatus = ConnectStatus.Connected;
  77. var stateObject = new StateObject(bufferSize: 512, tcpSocket);
  78. WaitForData(stateObject);
  79. }
  80. else
  81. {
  82. ConnectStatus = ConnectStatus.ConnectionFail;
  83. //Try Clear - disconnect
  84. Close();
  85. }
  86. }
  87. private void OnTcpConnectComplete(IAsyncResult ar)
  88. {
  89. if (tcpSocket.Connected)
  90. {
  91. ConnectStatus = ConnectStatus.Connected;
  92. var stateObject = new StateObject(bufferSize: 512, tcpSocket);
  93. WaitForData(stateObject);
  94. }
  95. else
  96. {
  97. ConnectStatus = ConnectStatus.ConnectionFail;
  98. }
  99. }
  100. private void WaitForData(StateObject stateObject)
  101. {
  102. try
  103. {
  104. var soc = stateObject.sSocket;
  105. if (!soc.Connected) { return; }
  106. IAsyncResult iar = soc.BeginReceive(
  107. stateObject.sBuffer,
  108. 0,
  109. stateObject.sBuffer.Length,
  110. SocketFlags.None,
  111. new AsyncCallback(ReveiveCallBack),
  112. stateObject);
  113. }
  114. catch (Exception e)
  115. {
  116. if (e != null)
  117. {
  118. if (e.Message != null)
  119. Console.WriteLine(e.Message);
  120. if (e.StackTrace != null)
  121. Console.WriteLine(e.StackTrace);
  122. }
  123. }
  124. }
  125. private void ReveiveCallBack(IAsyncResult ar)
  126. {
  127. StateObject stateObject = (StateObject)ar.AsyncState;
  128. if (!stateObject.sSocket.Connected)
  129. {
  130. //server Diconnected
  131. HandleDisconnected();
  132. return;
  133. }
  134. int bytesReceived;
  135. try
  136. {
  137. bytesReceived = stateObject.sSocket.EndReceive(ar);
  138. }
  139. catch (SocketException e)
  140. {
  141. if (e != null)
  142. {
  143. if (e.Message != null)
  144. System.Diagnostics.Debug.WriteLine(e.Message);
  145. if (e.StackTrace != null)
  146. System.Diagnostics.Debug.WriteLine(e.StackTrace);
  147. }
  148. //server Diconnected
  149. HandleDisconnected();
  150. return;
  151. }
  152. if (bytesReceived == 0)
  153. {
  154. stateObject.sSocket.Disconnect(true);
  155. HandleDisconnected();
  156. return;
  157. }
  158. byte[] receivedBytes = new byte[bytesReceived];
  159. Array.Copy(stateObject.sBuffer, 0, receivedBytes, 0, bytesReceived);
  160. OnDataReceived?.Invoke(this, receivedBytes);
  161. //continue receive
  162. WaitForData(stateObject);
  163. }
  164. private void HandleDisconnected()
  165. {
  166. Close();
  167. }
  168. }
  169. internal class StateObject
  170. {
  171. public byte[] sBuffer;
  172. public Socket sSocket;
  173. public StateObject(int bufferSize, Socket sock, int timeOutMilliSecond = -1)
  174. {
  175. sBuffer = new byte[bufferSize];
  176. sSocket = sock;
  177. }
  178. }
  179. }