IsoSocket.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. using PlcSiemens.O;
  2. using PlcSiemens.Protocol.Iso;
  3. using System.Net;
  4. using System.Net.Sockets;
  5. using ByteBuffer = PlcSiemens.O.ByteBuffer;
  6. namespace PlcSiemens.Communication
  7. {
  8. /// <summary>
  9. /// 采用同步通信机制
  10. /// </summary>
  11. public class IsoSocket : IIsoSender
  12. {
  13. private Socket _socket;
  14. public bool Connected
  15. {
  16. get
  17. {
  18. try
  19. {
  20. if (_socket == null)
  21. return false;
  22. //return _socket.Connected;
  23. //return _socket.Connected && (!(_socket.Available == 0) || !_socket.Poll(1000, SelectMode.SelectRead));
  24. return !(!_socket.Connected || (_socket.Poll(1000, SelectMode.SelectRead) && (_socket.Available == 0)));
  25. }
  26. catch
  27. {
  28. return false;
  29. }
  30. }
  31. }
  32. private Action<MessageEvent> _messageAction;
  33. public void RegisterMessage(Action<MessageEvent> messageAction)
  34. {
  35. if (messageAction == null) throw new ArgumentNullException("messageAction");
  36. _messageAction = messageAction;
  37. }
  38. private void OnMessage(string methode, string message)
  39. {
  40. if (_messageAction != null)
  41. _messageAction.Invoke(new MessageEvent(methode, message));
  42. }
  43. private int _connecting;//连接中
  44. private bool conneted = false;
  45. public bool Connect(string ip, int port)
  46. {
  47. try
  48. {
  49. conneted = false;
  50. if (Interlocked.CompareExchange(ref _connecting, 1, 0) != 0)
  51. {
  52. OnMessage("Connect", "连接正在处理中");
  53. return false;
  54. }
  55. _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  56. _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 1000);
  57. _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 1000);
  58. IPEndPoint server = new IPEndPoint(IPAddress.Parse(ip), 102);
  59. //_socket.Connect(server);
  60. //return true;
  61. timeoutObject.Reset();
  62. _socket.BeginConnect(server, new AsyncCallback(Callback), _socket);
  63. if (!timeoutObject.WaitOne(1000))
  64. {
  65. _socket.Close();
  66. conneted = false;
  67. }
  68. return conneted;
  69. }
  70. catch (Exception ex)
  71. {
  72. OnMessage("Connect", "连接异常:{ex.Message}");
  73. return false;
  74. }
  75. finally
  76. {
  77. Interlocked.CompareExchange(ref _connecting, 0, 1);
  78. }
  79. }
  80. private ManualResetEvent timeoutObject = new ManualResetEvent(false);
  81. private void Callback(IAsyncResult result)
  82. {
  83. try
  84. {
  85. var client = result.AsyncState as Socket;
  86. if (client != null)
  87. {
  88. client.EndConnect(result);
  89. conneted = true;
  90. }
  91. }
  92. catch (Exception ex)
  93. {
  94. conneted = false;
  95. }
  96. finally
  97. {
  98. timeoutObject.Set();
  99. }
  100. }
  101. private bool IsActive()
  102. {
  103. if (!Connected)
  104. {
  105. OnMessage("SendRecive", "未连接到PLC设备");
  106. return false;
  107. }
  108. if (Interlocked.CompareExchange(ref _sending, 1, 0) != 0)
  109. {
  110. OnMessage("SendRecive", "正在处理中");
  111. return false;
  112. }
  113. return true;
  114. }
  115. private int _sending;//发送中
  116. public byte[] SendRecive(byte[] sendBytes, int length)
  117. {
  118. try
  119. {
  120. if (!IsActive())
  121. return null;
  122. var sendStr = BitConverter.ToString(sendBytes, 0, length);
  123. //Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss ffff")}[Send]({length}):{sendStr}");
  124. _socket.Send(sendBytes, length, SocketFlags.None);
  125. byte[] bReceive = new byte[1024 * 8];
  126. var resLength = _socket.Receive(bReceive, SocketFlags.None);
  127. var recvStr = BitConverter.ToString(bReceive, 0, resLength);
  128. //Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss ffff")}[Recv]({resLength}):{recvStr}");
  129. var receiveBytes = new byte[resLength];
  130. Array.Copy(bReceive, 0, receiveBytes, 0, resLength);
  131. return receiveBytes;
  132. }
  133. catch (System.Net.Sockets.SocketException ex)
  134. {
  135. _socket.Close();
  136. OnMessage("Send", "连接断开:" + ex.Message);
  137. return null;
  138. }
  139. catch (Exception ex)
  140. {
  141. OnMessage("Send", "发送异常:" + ex.Message);
  142. return null;
  143. }
  144. finally
  145. {
  146. Interlocked.CompareExchange(ref _sending, 0, 1);
  147. }
  148. }
  149. private TResponse GetResponse<TResponse>(byte[] resBytes, bool isContainHeader = true)
  150. where TResponse : IBuildResponse, new()
  151. {
  152. ByteBuffer buffer = ByteBuffer.Allocate();
  153. buffer.Push(resBytes);
  154. if (isContainHeader)
  155. {
  156. IsoDataPdu pdu = new IsoDataPdu();
  157. pdu.Build(buffer);
  158. if (resBytes.Length != pdu.Length)
  159. return default(TResponse);
  160. }
  161. TResponse response = new TResponse();
  162. response.Build(buffer);
  163. return response;
  164. }
  165. private ByteBuffer GetByteBuffer<TRequest>(TRequest request, bool isContainHeader = true)
  166. where TRequest : IBuildRequest, new()
  167. {
  168. if (request == null) throw new ArgumentNullException("request");
  169. request.Build();
  170. var bufferData = request.GetBuffer();
  171. ByteBuffer buffer = ByteBuffer.Allocate();
  172. if (isContainHeader)
  173. {
  174. //构建ISO头部
  175. IsoDataPdu pdu = new IsoDataPdu { Length = (ushort)bufferData.WriteIndex };
  176. pdu.Build();
  177. pdu.GetBuffer(buffer);
  178. }
  179. buffer.Push(bufferData.Buffer, bufferData.WriteIndex);
  180. return buffer;
  181. }
  182. /// <summary>
  183. /// 不含ISO头的请求
  184. /// </summary>
  185. /// <typeparam name="TRequest"></typeparam>
  186. /// <typeparam name="TResponse"></typeparam>
  187. /// <param name="request"></param>
  188. /// <returns></returns>
  189. public TResponse Send<TRequest, TResponse>(TRequest request) where TRequest : IBuildRequest, new() where TResponse : IBuildResponse, new()
  190. {
  191. var buffer = GetByteBuffer(request, false);
  192. var resByte = SendRecive(buffer.Buffer, buffer.WriteIndex);
  193. if (resByte == null || resByte.Length == 0) return default(TResponse);
  194. return GetResponse<TResponse>(resByte, false);
  195. }
  196. /// <summary>
  197. /// 包含ISO头的请求
  198. /// </summary>
  199. /// <typeparam name="TRequest"></typeparam>
  200. /// <typeparam name="TResponse"></typeparam>
  201. /// <param name="request"></param>
  202. /// <returns></returns>
  203. public TResponse IsoSend<TRequest, TResponse>(TRequest request) where TRequest : IBuildRequest, new() where TResponse : IBuildResponse, new()
  204. {
  205. var buffer = GetByteBuffer(request);
  206. var resByte = SendRecive(buffer.Buffer, buffer.WriteIndex);
  207. if (resByte == null)
  208. return default(TResponse);
  209. return GetResponse<TResponse>(resByte);
  210. }
  211. }
  212. }