123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
-
- using System;
- using System.IO;
- namespace KYFramework.Network
- {
- public enum ParserState
- {
- PacketSize,
- PacketBody
- }
- public static class Packet
- {
- public const int PacketSizeLength2 = 2;
- public const int PacketSizeLength4 = 4;
- public const int MinPacketSize = 2;
- public const int OpcodeIndex = 0;
- public const int MessageIndex = 2;
- }
- public class PacketParser
- {
- private readonly CircularBuffer buffer;
- private int packetSize;
- private ParserState state;
- public MemoryStream memoryStream;
- private bool isOK;
- private readonly int packetSizeLength;
- public PacketParser(int packetSizeLength, CircularBuffer buffer, MemoryStream memoryStream)
- {
- this.packetSizeLength = packetSizeLength;
- this.buffer = buffer;
- this.memoryStream = memoryStream;
- }
- public bool Parse()
- {
- if (this.isOK)
- {
- return true;
- }
- bool finish = false;
- while (!finish)
- {
- switch (this.state)
- {
- case ParserState.PacketSize:
- if (this.buffer.Length < this.packetSizeLength)
- {
- finish = true;
- }
- else
- {
- this.buffer.Read(this.memoryStream.GetBuffer(), 0, this.packetSizeLength);
- switch (this.packetSizeLength)
- {
- case Packet.PacketSizeLength4:
- this.packetSize = BitConverter.ToInt32(this.memoryStream.GetBuffer(), 0);
- if (this.packetSize > ushort.MaxValue * 16 || this.packetSize < Packet.MinPacketSize)
- {
- throw new Exception($"recv packet size error: {this.packetSize}");
- }
- break;
- case Packet.PacketSizeLength2:
- this.packetSize = BitConverter.ToUInt16(this.memoryStream.GetBuffer(), 0);
- if (this.packetSize > ushort.MaxValue || this.packetSize < Packet.MinPacketSize)
- {
- throw new Exception($"recv packet size error: {this.packetSize}");
- }
- break;
- default:
- throw new Exception("packet size byte count must be 2 or 4!");
- }
- this.state = ParserState.PacketBody;
- }
- break;
- case ParserState.PacketBody:
- if (this.buffer.Length < this.packetSize)
- {
- finish = true;
- }
- else
- {
- this.memoryStream.Seek(0, SeekOrigin.Begin);
- this.memoryStream.SetLength(this.packetSize);
- byte[] bytes = this.memoryStream.GetBuffer();
- this.buffer.Read(bytes, 0, this.packetSize);
- this.isOK = true;
- this.state = ParserState.PacketSize;
- finish = true;
- }
- break;
- }
- }
- return this.isOK;
- }
- public MemoryStream GetPacket()
- {
- this.isOK = false;
- return this.memoryStream;
- }
- }
- }
|