CommunicationSequence.cs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using System;
  2. using System.Buffers;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Net;
  7. using System.Net.Sockets;
  8. using System.Threading.Tasks;
  9. namespace S7.Net.UnitTest;
  10. internal class CommunicationSequence : IEnumerable<RequestResponsePair>
  11. {
  12. private readonly List<RequestResponsePair> _requestResponsePairs = new List<RequestResponsePair>();
  13. public void Add(RequestResponsePair requestResponsePair)
  14. {
  15. _requestResponsePairs.Add(requestResponsePair);
  16. }
  17. public void Add(string requestPattern, string responsePattern)
  18. {
  19. _requestResponsePairs.Add(new RequestResponsePair(requestPattern, responsePattern));
  20. }
  21. public IEnumerator<RequestResponsePair> GetEnumerator()
  22. {
  23. return _requestResponsePairs.GetEnumerator();
  24. }
  25. IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
  26. public Task Serve(out int port)
  27. {
  28. var socket = CreateBoundListenSocket(out port);
  29. socket.Listen(0);
  30. async Task Impl()
  31. {
  32. await Task.Yield();
  33. var socketIn = socket.Accept();
  34. var buffer = ArrayPool<byte>.Shared.Rent(1024);
  35. try
  36. {
  37. foreach (var pair in _requestResponsePairs)
  38. {
  39. var bytesReceived = socketIn.Receive(buffer, SocketFlags.None);
  40. var received = buffer.Take(bytesReceived).ToArray();
  41. Console.WriteLine($"=> {BitConverter.ToString(received)}");
  42. var response = Responder.Respond(pair, received);
  43. Console.WriteLine($"<= {BitConverter.ToString(response)}");
  44. socketIn.Send(response);
  45. }
  46. }
  47. finally
  48. {
  49. ArrayPool<byte>.Shared.Return(buffer);
  50. }
  51. socketIn.Close();
  52. }
  53. return Impl();
  54. }
  55. private static Socket CreateBoundListenSocket(out int port)
  56. {
  57. var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  58. var endpoint = new IPEndPoint(IPAddress.Loopback, 0);
  59. socket.Bind(endpoint);
  60. var localEndpoint = (IPEndPoint)socket.LocalEndPoint!;
  61. port = localEndpoint.Port;
  62. return socket;
  63. }
  64. }