TPKT.cs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. using System;
  2. using System.IO;
  3. using System.Threading;
  4. using System.Threading.Tasks;
  5. namespace S7.Net
  6. {
  7. /// <summary>
  8. /// Describes a TPKT Packet
  9. /// </summary>
  10. internal class TPKT
  11. {
  12. public byte Version;
  13. public byte Reserved1;
  14. public int Length;
  15. public byte[] Data;
  16. private TPKT(byte version, byte reserved1, int length, byte[] data)
  17. {
  18. Version = version;
  19. Reserved1 = reserved1;
  20. Length = length;
  21. Data = data;
  22. }
  23. /// <summary>
  24. /// Reads a TPKT from the socket Async
  25. /// </summary>
  26. /// <param name="stream">The stream to read from</param>
  27. /// <param name="cancellationToken">A cancellation token that can be used to cancel the asynchronous operation.</param>
  28. /// <returns>Task TPKT Instace</returns>
  29. public static async Task<TPKT> ReadAsync(Stream stream, CancellationToken cancellationToken)
  30. {
  31. var buf = new byte[4];
  32. int len = await stream.ReadExactAsync(buf, 0, 4, cancellationToken).ConfigureAwait(false);
  33. if (len < 4) throw new TPKTInvalidException("TPKT is incomplete / invalid");
  34. var version = buf[0];
  35. var reserved1 = buf[1];
  36. var length = buf[2] * 256 + buf[3]; //BigEndian
  37. var data = new byte[length - 4];
  38. len = await stream.ReadExactAsync(data, 0, data.Length, cancellationToken).ConfigureAwait(false);
  39. if (len < data.Length)
  40. throw new TPKTInvalidException("TPKT payload incomplete / invalid");
  41. return new TPKT
  42. (
  43. version: version,
  44. reserved1: reserved1,
  45. length: length,
  46. data: data
  47. );
  48. }
  49. public override string ToString()
  50. {
  51. return string.Format("Version: {0} Length: {1} Data: {2}",
  52. Version,
  53. Length,
  54. BitConverter.ToString(Data)
  55. );
  56. }
  57. }
  58. }