AsyncSocketDevice.cs 8.8 KB

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