AsyncSocketDevice.cs 8.5 KB

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