SocketClient.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. using System;
  2. using System.Net;
  3. using System.Net.NetworkInformation;
  4. using System.Net.Sockets;
  5. using System.Text;
  6. using System.Threading;
  7. using Aitex.Core.RT.Log;
  8. using MECF.Framework.Common.Communications;
  9. namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Efems.Rorzes
  10. {
  11. public class SocketClient : IDisposable, IConnectable
  12. {
  13. public class ClientStateObject
  14. {
  15. // Client socket.
  16. public Socket workSocket = null;
  17. // Size of receive buffer.
  18. public static int BufferSize = 256;
  19. // Receive buffer.
  20. public byte[] buffer = new byte[BufferSize];
  21. // Received data string.
  22. public StringBuilder sb = new StringBuilder();
  23. public ClientStateObject(int bufferSize = 256)
  24. {
  25. BufferSize = bufferSize;
  26. buffer = new byte[bufferSize];
  27. }
  28. }
  29. public event Action<string> OnCommunicationError;
  30. public event Action<string> OnAsciiDataReceived;
  31. public event Action<byte[]> OnBinaryDataReceived;
  32. public bool IsConnected { get { return (_socket != null && _socket.Connected); } }
  33. private Socket _socket;
  34. private int _bufferSize = 256;
  35. private static Object _lockerSocket = new Object();
  36. private IConnectionContext _config;
  37. public SocketClient(IConnectionContext config)
  38. {
  39. _config = config;
  40. }
  41. ~SocketClient()
  42. {
  43. Dispose();
  44. }
  45. public void Connect()
  46. {
  47. try
  48. {
  49. string ip = _config.Address.Split(':')[0];
  50. int port = int.Parse(_config.Address.Split(':')[1]);
  51. IPAddress ipAddress = IPAddress.Parse(ip);
  52. IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
  53. lock (_lockerSocket)
  54. {
  55. Dispose();
  56. if (_socket == null)
  57. {
  58. _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  59. }
  60. _socket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), _socket);
  61. }
  62. }
  63. catch (Exception ex)
  64. {
  65. LOG.Error($"Failed connect, " + ex);
  66. }
  67. }
  68. private void ConnectCallback(IAsyncResult ar)
  69. {
  70. try
  71. {
  72. Socket client = (Socket)ar.AsyncState;
  73. if (client.Connected)
  74. {
  75. client.EndConnect(ar);
  76. ClientStateObject state = new ClientStateObject(_bufferSize);
  77. state.workSocket = _socket;
  78. _socket.BeginReceive(state.buffer, 0, ClientStateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
  79. }
  80. }
  81. catch (Exception ex)
  82. {
  83. LOG.Error($"Failed connect, " + ex);
  84. }
  85. }
  86. public bool Connect(out string reason)
  87. {
  88. Connect( );
  89. reason = string.Empty;
  90. return true;
  91. }
  92. public bool Disconnect(out string reason)
  93. {
  94. Dispose();
  95. reason = string.Empty;
  96. return true;
  97. }
  98. public bool CheckIsConnected()
  99. {
  100. if (!IsConnected)
  101. return false;
  102. lock (_lockerSocket)
  103. {
  104. if ((_socket.Poll(0, SelectMode.SelectWrite)) && (!_socket.Poll(0, SelectMode.SelectError)))
  105. {
  106. //byte[] buffer = new byte[1];
  107. //_socket.ReceiveTimeout
  108. //if (_socket.Receive(buffer, SocketFlags.Peek) == 0)
  109. //{
  110. // return false;
  111. //}
  112. //else
  113. //{
  114. return true;
  115. //}
  116. }
  117. else
  118. {
  119. return false;
  120. }
  121. }
  122. }
  123. public bool SendBinaryData(byte[] data)
  124. {
  125. try
  126. {
  127. lock (_lockerSocket)
  128. {
  129. _socket.BeginSend(data, 0, data.Length, 0, new AsyncCallback(SendCallback), _socket);
  130. if (_config.EnableLog)
  131. {
  132. LOG.Info($"Communication {_config.Address} Send {string.Join(" ", data)}." );
  133. }
  134. }
  135. return true;
  136. }
  137. catch (Exception ex)
  138. {
  139. LOG.Info($"Failed send {string.Join(" ", data)}, " + ex);
  140. NotifyError(ex.Message);
  141. }
  142. return false;
  143. }
  144. public bool SendAsciiData(string data)
  145. {
  146. try
  147. {
  148. lock (_lockerSocket)
  149. {
  150. byte[] byteData = Encoding.ASCII.GetBytes(data);
  151. _socket.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), _socket);
  152. if (_config.EnableLog)
  153. {
  154. LOG.Info($"Communication {_config.Address} Send {string.Join(" ", data.TrimEnd('\r', '\n'))}");
  155. }
  156. }
  157. return true;
  158. }
  159. catch (Exception ex)
  160. {
  161. LOG.Info($"Failed send {string.Join(" ", data)}, " + ex);
  162. NotifyError(ex.Message);
  163. }
  164. return false;
  165. }
  166. private void ReceiveCallback(IAsyncResult ar)
  167. {
  168. try
  169. {
  170. if (!IsConnected)
  171. {
  172. return;
  173. }
  174. ClientStateObject state = (ClientStateObject)ar.AsyncState;
  175. Socket client = state.workSocket;
  176. int bytesRead = client.EndReceive(ar);
  177. if (bytesRead > 0)
  178. {
  179. string receiveMessage = Encoding.ASCII.GetString(state.buffer, 0, bytesRead);
  180. state.sb.Append(receiveMessage);
  181. if (!_config.IsAscii)
  182. {
  183. byte[] recvBuff = new byte[bytesRead];
  184. for (int i = 0; i < bytesRead; i++)
  185. {
  186. recvBuff[i] = state.buffer[i];
  187. }
  188. if (_config.EnableLog)
  189. {
  190. LOG.Info($"Communication {_config.Address} receive {string.Join(" ", recvBuff)}.");
  191. }
  192. if (OnBinaryDataReceived != null)
  193. {
  194. OnBinaryDataReceived(recvBuff);
  195. }
  196. state.sb.Clear();
  197. }
  198. else if (state.sb.Length > _config.NewLine.Length)
  199. {
  200. if (state.sb.ToString().Substring(state.sb.Length - _config.NewLine.Length).Equals(_config.NewLine))
  201. {
  202. string msg = state.sb.ToString();
  203. if (_config.EnableLog)
  204. {
  205. LOG.Info($"Communication {_config.Address} receive {msg.TrimEnd('\r','\n')}");
  206. }
  207. if (OnAsciiDataReceived != null)
  208. {
  209. OnAsciiDataReceived(state.sb.ToString());
  210. }
  211. state.sb.Clear();
  212. }
  213. }
  214. // Get the rest of the data.
  215. client.BeginReceive(state.buffer, 0, ClientStateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
  216. }
  217. }
  218. catch (Exception ex)
  219. {
  220. LOG.Info($"Failed receive data, " + ex);
  221. NotifyError(ex.Message);
  222. }
  223. }
  224. private void SendCallback(IAsyncResult ar)
  225. {
  226. try
  227. {
  228. // Retrieve the socket from the state object.
  229. Socket client = (Socket)ar.AsyncState;
  230. // Complete sending the data to the remote device.
  231. int bytesSent = client.EndSend(ar);
  232. }
  233. catch (Exception ex)
  234. {
  235. LOG.Info($"Failed send data, " + ex);
  236. NotifyError(ex.Message);
  237. }
  238. }
  239. /// <summary>
  240. /// 释放资源(Dispose)
  241. /// </summary>
  242. public void Dispose()
  243. {
  244. try
  245. {
  246. if (_socket != null)
  247. {
  248. if (IsConnected)
  249. {
  250. _socket.Shutdown(SocketShutdown.Both);
  251. }
  252. _socket.Close();
  253. _socket.Dispose();
  254. _socket = null;
  255. }
  256. }
  257. catch (Exception ex)
  258. {
  259. LOG.Write($"Dispose {_config.Address} resource exception, {ex}");
  260. }
  261. }
  262. private void NotifyError(string reason)
  263. {
  264. if (OnCommunicationError != null)
  265. OnCommunicationError(reason);
  266. }
  267. private bool PingConnect()
  268. {
  269. bool result = true;
  270. if (_socket != null && _socket.Connected)
  271. {
  272. try
  273. {
  274. Ping pingTest = new Ping();
  275. PingReply reply = pingTest.Send(_config.Address.Split(':')[0]);
  276. if (reply.Status != IPStatus.Success)
  277. result = false;
  278. }
  279. catch (PingException) { result = false; }
  280. if (_socket.Poll(1000, SelectMode.SelectRead) && (_socket.Available == 0))
  281. {
  282. result = false;
  283. }
  284. }
  285. else
  286. {
  287. result = false;
  288. }
  289. return result;
  290. }
  291. }
  292. }