PacketParser.cs 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. using System;
  2. namespace Base
  3. {
  4. internal enum ParserState
  5. {
  6. PacketSize,
  7. PacketBody
  8. }
  9. internal class PacketParser
  10. {
  11. private readonly TBuffer buffer;
  12. private uint packetSize;
  13. private readonly byte[] packetSizeBuffer = new byte[4];
  14. private ParserState state;
  15. private byte[] packet;
  16. private bool isOK;
  17. public PacketParser(TBuffer buffer)
  18. {
  19. this.buffer = buffer;
  20. }
  21. public bool Parse()
  22. {
  23. if (this.isOK)
  24. {
  25. return true;
  26. }
  27. bool finish = false;
  28. while (!finish)
  29. {
  30. switch (this.state)
  31. {
  32. case ParserState.PacketSize:
  33. if (this.buffer.Count < 4)
  34. {
  35. finish = true;
  36. }
  37. else
  38. {
  39. this.buffer.RecvFrom(this.packetSizeBuffer);
  40. this.packetSize = BitConverter.ToUInt32(this.packetSizeBuffer, 0);
  41. if (packetSize > 1024 * 1024)
  42. {
  43. throw new Exception($"packet too large, size: {this.packetSize}");
  44. }
  45. this.state = ParserState.PacketBody;
  46. }
  47. break;
  48. case ParserState.PacketBody:
  49. if (this.buffer.Count < this.packetSize)
  50. {
  51. finish = true;
  52. }
  53. else
  54. {
  55. this.packet = new byte[this.packetSize];
  56. this.buffer.RecvFrom(this.packet);
  57. this.isOK = true;
  58. this.state = ParserState.PacketSize;
  59. finish = true;
  60. }
  61. break;
  62. }
  63. }
  64. return this.isOK;
  65. }
  66. public byte[] GetPacket()
  67. {
  68. byte[] result = this.packet;
  69. this.isOK = false;
  70. return result;
  71. }
  72. }
  73. }