AsyncSocketDevice.cs 8.8 KB

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