PacketParser.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. 
  2. using System;
  3. using System.IO;
  4. namespace KYFramework.Network
  5. {
  6. public enum ParserState
  7. {
  8. PacketSize,
  9. PacketBody
  10. }
  11. public static class Packet
  12. {
  13. public const int PacketSizeLength2 = 2;
  14. public const int PacketSizeLength4 = 4;
  15. public const int MinPacketSize = 2;
  16. public const int OpcodeIndex = 0;
  17. public const int MessageIndex = 2;
  18. }
  19. public class PacketParser
  20. {
  21. private readonly CircularBuffer buffer;
  22. private int packetSize;
  23. private ParserState state;
  24. public MemoryStream memoryStream;
  25. private bool isOK;
  26. private readonly int packetSizeLength;
  27. public PacketParser(int packetSizeLength, CircularBuffer buffer, MemoryStream memoryStream)
  28. {
  29. this.packetSizeLength = packetSizeLength;
  30. this.buffer = buffer;
  31. this.memoryStream = memoryStream;
  32. }
  33. public bool Parse()
  34. {
  35. if (this.isOK)
  36. {
  37. return true;
  38. }
  39. bool finish = false;
  40. while (!finish)
  41. {
  42. switch (this.state)
  43. {
  44. case ParserState.PacketSize:
  45. if (this.buffer.Length < this.packetSizeLength)
  46. {
  47. finish = true;
  48. }
  49. else
  50. {
  51. this.buffer.Read(this.memoryStream.GetBuffer(), 0, this.packetSizeLength);
  52. switch (this.packetSizeLength)
  53. {
  54. case Packet.PacketSizeLength4:
  55. this.packetSize = BitConverter.ToInt32(this.memoryStream.GetBuffer(), 0);
  56. if (this.packetSize > ushort.MaxValue * 16 || this.packetSize < Packet.MinPacketSize)
  57. {
  58. throw new Exception($"recv packet size error: {this.packetSize}");
  59. }
  60. break;
  61. case Packet.PacketSizeLength2:
  62. this.packetSize = BitConverter.ToUInt16(this.memoryStream.GetBuffer(), 0);
  63. if (this.packetSize > ushort.MaxValue || this.packetSize < Packet.MinPacketSize)
  64. {
  65. throw new Exception($"recv packet size error: {this.packetSize}");
  66. }
  67. break;
  68. default:
  69. throw new Exception("packet size byte count must be 2 or 4!");
  70. }
  71. this.state = ParserState.PacketBody;
  72. }
  73. break;
  74. case ParserState.PacketBody:
  75. if (this.buffer.Length < this.packetSize)
  76. {
  77. finish = true;
  78. }
  79. else
  80. {
  81. this.memoryStream.Seek(0, SeekOrigin.Begin);
  82. this.memoryStream.SetLength(this.packetSize);
  83. byte[] bytes = this.memoryStream.GetBuffer();
  84. this.buffer.Read(bytes, 0, this.packetSize);
  85. this.isOK = true;
  86. this.state = ParserState.PacketSize;
  87. finish = true;
  88. }
  89. break;
  90. }
  91. }
  92. return this.isOK;
  93. }
  94. public MemoryStream GetPacket()
  95. {
  96. this.isOK = false;
  97. return this.memoryStream;
  98. }
  99. }
  100. }