using System; using System.IO; using MrWu.Debug; namespace Server.Net { public enum ParserState{ PacketSize, PacketBody, } public class PacketParser { /// /// 收包Buffer /// private readonly CircularBuffer buffer; /// /// 当前要解的包大小 /// private int packetSize; private ParserState state; private readonly AService service; private readonly byte[] cache = new byte[4]; public const int ActorPacketSizeLength = 4; public const int RouterPacketSizeLength = 4; public MemoryBuffer MemoryBuffer; public PacketParser(CircularBuffer buffer, AService service) { this.buffer = buffer; this.service = service; } /// /// 解包到memoryBuffer /// /// /// public bool Parse(out MemoryBuffer memoryBuffer) { while (true) { switch (this.state) { //解析包头 case ParserState.PacketSize: //Actor 消息 if (this.service.ServiceType == ServiceType.Actor) { if (this.buffer.Length < ActorPacketSizeLength) { memoryBuffer = null; return false; } this.buffer.Read(this.cache, 0, ActorPacketSizeLength); this.packetSize = BitConverter.ToInt32(this.cache, 0); //todo 检查包大小是否正常 if (this.packetSize > ushort.MaxValue * 16 || this.packetSize < Packet.MinPacketSize) { throw new Exception($"recv packet size error, 接收包大小错误! {this.packetSize}"); } } else { //路由来的消息 if (this.buffer.Length < RouterPacketSizeLength) { memoryBuffer = null; return false; } this.buffer.Read(this.cache, 0, RouterPacketSizeLength); this.packetSize = BitConverter.ToUInt16(this.cache, 0); if (this.packetSize < Packet.OpcodeLength || this.packetSize > ushort.MaxValue) { throw new Exception($"recv packet size error,Router 消息大小错误! {this.packetSize}"); } } this.state = ParserState.PacketBody; break; //解析包体 case ParserState.PacketBody: if (this.buffer.Length < this.packetSize) { memoryBuffer = null; return false; } memoryBuffer = this.service.Fetch(this.packetSize); this.buffer.Read(memoryBuffer, this.packetSize); memoryBuffer.Seek(0, SeekOrigin.Begin); this.state = ParserState.PacketSize; return true; default: //不存在的情况 throw new ArgumentOutOfRangeException(); } } } } }