AsyncSocketDevice.cs 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. using System;
  2. using System.Text;
  3. using System.Net.Sockets;
  4. using System.Net;
  5. using Aitex.Core.RT.Event;
  6. using MECF.Framework.Common.Equipment;
  7. using Aitex.Core.RT.Log;
  8. using System.Diagnostics;
  9. using Aitex.Core.RT.SCCore;
  10. namespace MECF.Framework.Common.Communications
  11. {
  12. public class ErrorEventArgsDevice : EventArgs
  13. {
  14. public readonly string Reason;
  15. public readonly string Code;
  16. public ErrorEventArgsDevice(string reason, string code = "")
  17. {
  18. Reason = reason;
  19. Code = code;
  20. }
  21. }
  22. public class AsyncSocketDevice : IDisposable
  23. {
  24. public delegate void ErrorHandler(ErrorEventArgsDevice args);
  25. public event ErrorHandler OnErrorHappened;
  26. public delegate void MessageHandler(byte[] rawMessage);
  27. public event MessageHandler OnDataChanged;
  28. private static Object _locker = new Object();
  29. public class ClientStateObject
  30. {
  31. // Client socket.
  32. public Socket workSocket = null;
  33. // Size of receive buffer.
  34. public const int BufferSize = 256;
  35. // Receive buffer.
  36. public byte[] buffer = new byte[BufferSize];
  37. // Received data string.
  38. public StringBuilder sb = new StringBuilder();
  39. }
  40. public string NewLine { get; set; }
  41. private Socket _socket;
  42. private string _ip;
  43. private int _port;
  44. public bool IsConnected { get { return (_socket != null && _socket.Connected); } }
  45. public AsyncSocketDevice(string address, string newline = "\r")
  46. {
  47. // Connect(address);
  48. _socket = null;
  49. NewLine = newline;
  50. }
  51. ~AsyncSocketDevice()
  52. {
  53. Dispose();
  54. }
  55. public void Connect(string address)
  56. {
  57. try
  58. {
  59. _ip = address.Split(':')[0];
  60. _port = int.Parse(address.Split(':')[1]);
  61. IPAddress ipAddress = IPAddress.Parse(_ip);
  62. IPEndPoint remoteEP = new IPEndPoint(ipAddress, _port);
  63. //Dispose current socket and create a TCP/IP socket.
  64. Dispose();
  65. if (_socket == null)
  66. _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  67. // Connect to the remote endpoint.
  68. _socket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), _socket);
  69. }
  70. catch (Exception e)
  71. {
  72. //LOG.Write(e);
  73. throw new Exception(e.ToString());
  74. }
  75. }
  76. private void ConnectCallback(IAsyncResult ar)
  77. {
  78. try
  79. {
  80. // Retrieve the socket from the state object.
  81. Socket client = (Socket)ar.AsyncState;
  82. // Complete the connection.
  83. client.EndConnect(ar);
  84. //EV.PostMessage(ModuleName.Robot.ToString(), EventEnum.TCPConnSucess, _ip, _port.ToString());
  85. // Receive the response from the remote device.
  86. Receive(_socket);
  87. }
  88. catch (Exception e)
  89. {
  90. //LOG.Write(e);
  91. string reason = string.Format("Communication {0}:{1:D} {2}.", _ip, _port, e.Message);
  92. LOG.Write(eEvent.ERR_DEVICE_INFO, ModuleName.System, reason);
  93. //LOG.Error(reason);
  94. // EV.PostMessage(UnitName.Transfer.ToString(), EventEnum.RobotCommandFailed, reason);
  95. OnErrorHappened(new ErrorEventArgsDevice(reason));
  96. }
  97. }
  98. private void Receive(Socket client)
  99. {
  100. try
  101. {
  102. // Create the state object.
  103. ClientStateObject state = new ClientStateObject();
  104. state.workSocket = client;
  105. // Begin receiving the data from the remote device.
  106. client.BeginReceive(state.buffer, 0, ClientStateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
  107. }
  108. catch (Exception e)
  109. {
  110. //LOG.Write(e);
  111. string reason = string.Format("TCP连接发生错误:{0}", e.Message);
  112. LOG.Write(eEvent.ERR_DEVICE_INFO, ModuleName.System, reason);
  113. //LOG.Error(string.Format("Communication {0}:{1:D} {2}.", _ip, _port, reason));
  114. OnErrorHappened(new ErrorEventArgsDevice(reason));
  115. }
  116. }
  117. private void ReceiveCallback(IAsyncResult ar)
  118. {
  119. try
  120. {
  121. if (!IsConnected) { return; }
  122. // Retrieve the state object and the client socket
  123. // from the asynchronous state object.
  124. ClientStateObject state = (ClientStateObject)ar.AsyncState;
  125. Socket client = state.workSocket;
  126. // Read data from the remote device.
  127. int bytesRead = client.EndReceive(ar);
  128. if (bytesRead > 0)
  129. {
  130. // There might be more data, so store the data received so far.
  131. state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
  132. if (state.sb.Length > NewLine.Length)
  133. {
  134. string msg = state.sb.ToString();
  135. //LOG.Info(string.Format("Communication {0}:{1:D} receive {2}.", _ip, _port, BitConverter.ToString(state.buffer, 0, 6 + BitConverter.ToInt32(new byte[] { state.buffer[5], 0x00, 0x00, 0x00 }, 0))));
  136. OnDataChanged(state.buffer);
  137. state.sb.Clear();
  138. }
  139. // Get the rest of the data.
  140. client.BeginReceive(state.buffer, 0, ClientStateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
  141. }
  142. }
  143. catch (Exception ex)
  144. {
  145. //LOG.WriteExeption(ex);
  146. string reason = string.Format("TCP Socket recevice data failed:{0}", ex.Message);
  147. //LOG.Write(eEvent.ERR_DEVICE_INFO, ModuleName.System, reason);
  148. LOG.Error(string.Format("Communication {0}:{1:D} {2}.", _ip, _port, reason));
  149. OnErrorHappened(new ErrorEventArgsDevice(reason));
  150. }
  151. }
  152. public bool Write(byte[] byteData)
  153. {
  154. try
  155. {
  156. if (_socket.Connected)
  157. // Convert the string data to byte data using ASCII encoding.
  158. //byte[] byteData = Encoding.ASCII.GetBytes(data);
  159. _socket.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), _socket);
  160. if (SC.GetValue<bool>("System.EnableDeviceLog"))
  161. {
  162. LOG.Write(eEvent.EV_DEVICE_INFO, ModuleName.System, $"Communication {_ip}:{_port} Send {System.Text.Encoding.Default.GetString(byteData)}.");
  163. }
  164. //LOG.Info(string.Format("Communication {0}:{1:D} Send {2}.", _ip, _port, data.TrimEnd('\n').TrimEnd('\r')));
  165. //lock (_locker)
  166. //{
  167. //}
  168. return true;
  169. }
  170. catch (Exception ex)
  171. {
  172. //LOG.WriteExeption(ex);
  173. //LOG.Info(string.Format("Communication {0}:{1:D} Send {2}. failed", _ip, _port, data));
  174. string reason = string.Format("Send command failed:{0}", ex.Message);
  175. LOG.Write(eEvent.ERR_DEVICE_INFO, ModuleName.System, reason);
  176. OnErrorHappened(new ErrorEventArgsDevice(reason));
  177. }
  178. return false;
  179. }
  180. private void SendCallback(IAsyncResult ar)
  181. {
  182. try
  183. {
  184. // Retrieve the socket from the state object.
  185. Socket client = (Socket)ar.AsyncState;
  186. // Complete sending the data to the remote device.
  187. int bytesSent = client.EndSend(ar);
  188. }
  189. catch (Exception ex)
  190. {
  191. //LOG.WriteExeption(ex);
  192. string reason = string.Format("Send command failed:{0}", ex.Message);
  193. OnErrorHappened(new ErrorEventArgsDevice(reason));
  194. }
  195. }
  196. /// <summary>
  197. /// 释放资源(Dispose)
  198. /// </summary>
  199. public void Dispose()
  200. {
  201. try
  202. {
  203. LOG.Write(eEvent.EV_DEVICE_INFO, ModuleName.System, $"{_ip}关闭");
  204. if (_socket != null)
  205. {
  206. if (IsConnected)
  207. {
  208. _socket.Shutdown(SocketShutdown.Both);
  209. }
  210. _socket.Close();
  211. _socket.Dispose();
  212. _socket = null;
  213. }
  214. }
  215. catch (Exception ex)
  216. {
  217. //LOG.WriteExeption(ex);
  218. string reason = string.Format("释放socket资源失败:{0}", ex.Message);
  219. LOG.Write(eEvent.ERR_DEVICE_INFO, ModuleName.System, reason);
  220. OnErrorHappened(new ErrorEventArgsDevice(reason));
  221. }
  222. }
  223. public bool ReConnect(string ip=null)
  224. {
  225. if (IsConnected)
  226. {
  227. return true;
  228. }
  229. //_socket.Shutdown(SocketShutdown.Both);
  230. _socket.Close();
  231. _socket.Dispose();
  232. string address=ip==null?_ip:ip;
  233. Connect(address);
  234. return IsConnected;
  235. }
  236. }
  237. }