|
|
@@ -4,54 +4,18 @@ namespace Base
|
|
|
{
|
|
|
internal enum ParserState
|
|
|
{
|
|
|
- PacketHeader,
|
|
|
- MessageHeaderSize,
|
|
|
- MessageHeader,
|
|
|
- MessageBodySize,
|
|
|
- MessageBody,
|
|
|
- }
|
|
|
-
|
|
|
- internal class Packet
|
|
|
- {
|
|
|
- public PacketHeader packetHeader = new PacketHeader();
|
|
|
- public MessageHeader messageHeader = new MessageHeader();
|
|
|
- public MessageBody messageBody = new MessageBody();
|
|
|
- }
|
|
|
-
|
|
|
- internal class PacketHeader
|
|
|
- {
|
|
|
- public uint Flag;
|
|
|
- public uint Size;
|
|
|
- }
|
|
|
-
|
|
|
- internal class MessageHeader
|
|
|
- {
|
|
|
- public int Size;
|
|
|
- public byte Format;
|
|
|
- public int Status;
|
|
|
- public int Seq;
|
|
|
- public long Session;
|
|
|
- public byte[] Command = new byte[4];
|
|
|
- public byte[] Module;
|
|
|
- }
|
|
|
-
|
|
|
- internal class MessageBody
|
|
|
- {
|
|
|
- public int Size;
|
|
|
- public byte[] Content;
|
|
|
+ PacketSize,
|
|
|
+ PacketBody
|
|
|
}
|
|
|
|
|
|
internal class PacketParser
|
|
|
{
|
|
|
private readonly TBuffer buffer;
|
|
|
|
|
|
- private readonly byte[] intBuffer = new byte[4];
|
|
|
- private readonly byte[] longBuffer = new byte[8];
|
|
|
- private readonly byte[] byteBuffer = new byte[1];
|
|
|
-
|
|
|
- private Packet packet = new Packet();
|
|
|
-
|
|
|
+ private uint packetSize;
|
|
|
+ private readonly byte[] packetSizeBuffer = new byte[4];
|
|
|
private ParserState state;
|
|
|
+ private byte[] packet;
|
|
|
private bool isOK;
|
|
|
|
|
|
public PacketParser(TBuffer buffer)
|
|
|
@@ -71,85 +35,33 @@ namespace Base
|
|
|
{
|
|
|
switch (this.state)
|
|
|
{
|
|
|
- case ParserState.PacketHeader:
|
|
|
- if (this.buffer.Count < 8)
|
|
|
+ case ParserState.PacketSize:
|
|
|
+ if (this.buffer.Count < 4)
|
|
|
{
|
|
|
finish = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- this.buffer.RecvFrom(this.intBuffer);
|
|
|
- this.packet.packetHeader.Flag = BitConverter.ToUInt32(this.intBuffer, 0);
|
|
|
- this.buffer.RecvFrom(this.intBuffer);
|
|
|
- this.packet.packetHeader.Size = BitConverter.ToUInt32(this.intBuffer, 0);
|
|
|
- if (this.packet.packetHeader.Size > 1024 * 1024)
|
|
|
+ this.buffer.RecvFrom(this.packetSizeBuffer);
|
|
|
+ this.packetSize = BitConverter.ToUInt32(this.packetSizeBuffer, 0);
|
|
|
+ if (packetSize > 1024 * 1024)
|
|
|
{
|
|
|
- throw new Exception($"packet too large, size: {this.packet.packetHeader.Size}");
|
|
|
+ throw new Exception($"packet too large, size: {this.packetSize}");
|
|
|
}
|
|
|
- this.state = ParserState.MessageHeaderSize;
|
|
|
- }
|
|
|
- break;
|
|
|
- case ParserState.MessageHeaderSize:
|
|
|
- if (this.buffer.Count < 4)
|
|
|
- {
|
|
|
- finish = true;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- this.buffer.RecvFrom(this.intBuffer);
|
|
|
- this.packet.messageHeader.Size = BitConverter.ToInt32(this.intBuffer, 0);
|
|
|
- finish = true;
|
|
|
- }
|
|
|
- break;
|
|
|
- case ParserState.MessageHeader:
|
|
|
- if (this.buffer.Count < this.packet.messageHeader.Size)
|
|
|
- {
|
|
|
- finish = true;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- this.buffer.RecvFrom(this.byteBuffer);
|
|
|
- this.packet.messageHeader.Format = this.byteBuffer[0];
|
|
|
-
|
|
|
- this.buffer.RecvFrom(this.intBuffer);
|
|
|
- this.packet.messageHeader.Status = BitConverter.ToInt32(this.intBuffer, 0);
|
|
|
-
|
|
|
- this.buffer.RecvFrom(this.intBuffer);
|
|
|
- this.packet.messageHeader.Seq = BitConverter.ToInt32(this.intBuffer, 0);
|
|
|
-
|
|
|
- this.buffer.RecvFrom(this.longBuffer);
|
|
|
- this.packet.messageHeader.Session = BitConverter.ToInt64(this.longBuffer, 0);
|
|
|
-
|
|
|
- this.buffer.RecvFrom(this.packet.messageHeader.Command);
|
|
|
-
|
|
|
- this.packet.messageHeader.Module = new byte[this.packet.messageHeader.Size - 21];
|
|
|
- this.buffer.RecvFrom(this.packet.messageHeader.Module);
|
|
|
-
|
|
|
- finish = true;
|
|
|
- }
|
|
|
- break;
|
|
|
-
|
|
|
- case ParserState.MessageBodySize:
|
|
|
- if (this.buffer.Count < 4)
|
|
|
- {
|
|
|
- finish = true;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- this.buffer.RecvFrom(this.intBuffer);
|
|
|
- this.packet.messageBody.Size = BitConverter.ToInt32(this.intBuffer, 0);
|
|
|
- finish = true;
|
|
|
+ this.state = ParserState.PacketBody;
|
|
|
}
|
|
|
break;
|
|
|
- case ParserState.MessageBody:
|
|
|
- if (this.buffer.Count < this.packet.messageBody.Size)
|
|
|
+ case ParserState.PacketBody:
|
|
|
+ if (this.buffer.Count < this.packetSize)
|
|
|
{
|
|
|
finish = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- this.packet.messageBody.Content = new byte[this.packet.messageBody.Size];
|
|
|
- this.buffer.RecvFrom(this.packet.messageBody.Content);
|
|
|
+ this.packet = new byte[this.packetSize];
|
|
|
+ this.buffer.RecvFrom(this.packet);
|
|
|
+ this.isOK = true;
|
|
|
+ this.state = ParserState.PacketSize;
|
|
|
finish = true;
|
|
|
}
|
|
|
break;
|
|
|
@@ -164,9 +76,7 @@ namespace Base
|
|
|
{
|
|
|
return null;
|
|
|
}
|
|
|
- byte[] result = new byte[4 + this.packet.messageBody.Content.Length];
|
|
|
- Array.Copy(result, this.packet.messageHeader.Command, 4);
|
|
|
- Array.Copy(result, 4, this.packet.messageBody.Content, 0, this.packet.messageBody.Content.Length);
|
|
|
+ byte[] result = this.packet;
|
|
|
this.isOK = false;
|
|
|
return result;
|
|
|
}
|