写的一个封拆包代码

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Xse
{
    namespace Protocol
    {
        public interface IPacket
        {
            byte[] ToArray();
        }

        public interface IBinaryData
        {
            void write(BinaryPacketWriter w);
            bool read(BinaryPacketReader r);
        }


        public class BinaryPacketWriter : BinaryWriter
        {
            Encoding myEncoding = Encoding.UTF8;
            public Encoding Encoding { get { return myEncoding; } set { myEncoding = value; } }

            public int Left { get { return (int)(BaseStream.Length - BaseStream.Position); } }

            public BinaryPacketWriter(Stream s) : base(s) { }
            public BinaryPacketWriter(Stream s, Encoding encoding) : base(s) { myEncoding = encoding; }

            public void WriteTinyString(string val)
            {
                byte[] ary = Encoding.GetBytes(val);
                byte len = (byte)ary.Length;
                Write(len);
                Write(ary, 0, len);
            }
            public void WriteMediumString(string val)
            {
                byte[] ary = Encoding.GetBytes(val);
                UInt16 len = (UInt16)ary.Length;
                Write(len);
                Write(ary, 0, len);
            }
            public void WriteLongString(string val)
            {
                byte[] ary = Encoding.GetBytes(val);
                int len = ary.Length;
                Write(len);
                Write(ary, 0, len);
            }
            public void WriteString(string val)
            {
                byte[] ary = Encoding.GetBytes(val);
                Write(ary, 0, ary.Length);
            }
        }

        public class BinaryPacketReader : BinaryReader
        {

            Encoding myEncoding = Encoding.UTF8;
            public Encoding Encoding { get { return myEncoding; } set { myEncoding = value; } }

            public int Left { get { return (int)(BaseStream.Length - BaseStream.Position); } }

            public BinaryPacketReader(Stream s) : base(s) { }
            public BinaryPacketReader(Stream s, Encoding encoding) : base(s) { myEncoding = encoding; }



            public string ReadTinyString()
            {
                byte len = this.ReadByte();
                byte[] ary = this.ReadBytes(len);
                return myEncoding.GetString(ary);
            }
            public string ReadMediumString()
            {
                UInt16 len = this.ReadUInt16();
                byte[] ary = this.ReadBytes(len);
                return myEncoding.GetString(ary);
            }
            public string ReadLongString()
            {
                int len = this.ReadInt32();
                byte[] ary = this.ReadBytes(len);
                return myEncoding.GetString(ary);
            }

            public string ReadLeftAsString()
            {
                int len = (int)(BaseStream.Length - BaseStream.Position);
                byte[] ary = this.ReadBytes(len);
                return myEncoding.GetString(ary);
            }

            public string ReadString(int size)
            {
                byte[] ary = this.ReadBytes(size);
                int pos = Array.IndexOf<byte>(ary, 0);
                if (pos < 0) pos = size;
                return myEncoding.GetString(ary, 0, pos);
            }
        }

        public class BinaryPacket : IDisposable, IPacket
        {
            byte[] myArray = null;
            MemoryStream myDataStream = null;
            public MemoryStream DataStream { get { return myDataStream; } }

            BinaryPacketReader myReader = null;
            BinaryPacketWriter myWriter = null;

            public BinaryPacketWriter Writer { get { if (myWriter == null)myWriter = new BinaryPacketWriter(DataStream); return myWriter; } }
            public BinaryPacketReader Reader { get { if (myReader == null)myReader = new BinaryPacketReader(DataStream); return myReader; } }

            #region IPacket 成员

            public virtual byte[] ToArray()
            {
                //throw new NotImplementedException();
                byte[] ary = new byte[myDataStream.Length];
                myDataStream.Read(ary, 0, (int)myDataStream.Length);
                return ary;
            }

            #endregion

            public BinaryPacket(byte[] data)
            {
                myArray = data;
                myDataStream = new MemoryStream(myArray);
            }

            public BinaryPacket(byte[] data, int ofs, int len)
            {
                myArray = data;
                myDataStream = new MemoryStream(myArray, ofs, len);
            }

            #region IDisposable 成员

            public void Dispose()
            {
                myDataStream = null;
                myArray = null;
            }

            #endregion
        }

        public class SimpleBinaryPacket : IDisposable, IPacket
        {
            public const int HEADER_SIZE = sizeof(ushort) * 2;
            byte[] myArray = null;
            MemoryStream myDataStream = null;
            UInt16 myCommand = 0;
            public UInt16 Command { get { return myCommand; } }
            public MemoryStream DataStream { get { return myDataStream; } }

            BinaryPacketReader myReader = null;
            BinaryPacketWriter myWriter = null;

            public BinaryPacketWriter Writer { get { if (myWriter == null)myWriter = new BinaryPacketWriter(DataStream); return myWriter; } }
            public BinaryPacketReader Reader { get { if (myReader == null)myReader = new BinaryPacketReader(DataStream); return myReader; } }

            public int TotalLength { get { return sizeof(UInt16) * 2 + (int)DataStream.Length; } }


            public SimpleBinaryPacket(byte[] data, int ofs, int len)
            {
                myArray = data;
                if (len >= HEADER_SIZE)
                {
                    myCommand = (UInt16)(((UInt16)data[ofs + 2]) | (((UInt16)data[ofs + 3]) << 8));
                    ofs += HEADER_SIZE;
                    len -= HEADER_SIZE;
                }
                myDataStream = new MemoryStream(myArray, ofs, len);
            }

            public SimpleBinaryPacket(UInt16 cmd)
            {
                myCommand = cmd;
                myDataStream = new MemoryStream();
            }

            internal void WriteTo(Stream s)
            {
                BinaryWriter br = new BinaryWriter(s);
                ushort len = (ushort)myDataStream.Length;
                br.Write(len);
                br.Write(Command);
                br.Write(myDataStream.GetBuffer(), 0, len);
            }

            public byte[] ToArray()
            {
                byte[] ary = new byte[HEADER_SIZE + myDataStream.Length];
                MemoryStream ms = new MemoryStream(ary);
                WriteTo(ms);
                return ary;
            }

            #region IDisposable 成员

            public void Dispose()
            {
                myDataStream = null;
                myArray = null;
            }

            #endregion
        }

        public delegate void OnPacketEventHandler(byte[] data, int ofs, int len);
        public class SimpleBinaryProtocolParser
        {
            const int HEADER_SIZE = 4;
            const int SIZEFIELD_SIZE = 2;
            const int MAX_CACHE_SIZE = 65539;
            byte[] myCacheArray = new byte[MAX_CACHE_SIZE + 1];
            int myCacheLength = 0;
            int myCachePacketLength = 0;

            //public virtual void HandlePacket(byte[] data, int ofs, int len) { }
            public event OnPacketEventHandler OnPacket = null;

            int readPacketLength(byte[] data, int ofs)
            {
                return HEADER_SIZE + (int)(((UInt16)data[ofs]) | (((UInt16)data[ofs + 1]) << 8));
            }

            public static ushort readCommand(byte[] data, int ofs)
            {
                return (ushort)(((ushort)data[ofs]) | (((ushort)data[ofs + 1]) << 8));
            }

            bool writeCache(byte[] data, int ofs, int len)
            {
                if (myCacheLength + len > MAX_CACHE_SIZE) return false;
                Array.Copy(data, ofs, myCacheArray, myCacheLength, len);
                myCacheLength += len;
                if (myCachePacketLength == 0 &&
                    myCacheLength >= SIZEFIELD_SIZE)
                    myCachePacketLength = readPacketLength(myCacheArray, 0);
                return true;
            }

            int readPacket(byte[] data, int ofs, int endofs)
            {
                int left = endofs - ofs;
                if (left < SIZEFIELD_SIZE) return ofs;
                int datalen = readPacketLength(data, ofs);
                if (left < datalen) return ofs;
                return (ofs + datalen);
            }

            int readPackets(byte[] data, int ofs, int endofs)
            {
                int ptr = readPacket(data, ofs, endofs);
                while (ptr > ofs)
                {
                    if (OnPacket != null) OnPacket(data, ofs, ptr - ofs);
                    //HandlePacket(data, ofs, ptr - ofs);
                    ofs = ptr;
                    ptr = readPacket(data, ofs, endofs);
                }
                return ptr;
            }

            public bool HandleData(byte[] data)
            {
                return HandleData(data, 0, data.Length);
            }

            public bool HandleData(byte[] data, int ofs, int len)
            {
                int endofdata = ofs + len;
                if (myCacheLength == 0)
                {
                    int ptr = readPackets(data, ofs, endofdata);
                    if (ptr < endofdata)
                    {
                        return writeCache(data, ptr, endofdata - ptr);
                    }
                }
                else
                {
                    int needlen = 0;
                    if (myCachePacketLength == 0)
                    {
                        needlen = SIZEFIELD_SIZE - myCacheLength;
                        if (needlen >= len)
                        {
                            return writeCache(data, ofs, len);
                        }
                        if (!writeCache(data, ofs, needlen)) return false;
                        ofs += needlen;
                        len -= needlen;
                    }

                    needlen = myCachePacketLength - myCacheLength;
                    if (needlen > len)
                    {
                        return writeCache(data, ofs, len);
                    }
                    if (!writeCache(data, ofs, needlen)) return false;
                    ofs += needlen;
                    //len -= needlen;

                    if (OnPacket != null) OnPacket(myCacheArray, 0, myCachePacketLength);
                    myCacheLength = 0;
                    myCachePacketLength = 0;

                    if (ofs < endofdata)
                    {
                        ofs = readPackets(data, ofs, endofdata);

                        if (ofs < endofdata)
                            return writeCache(data, ofs, endofdata - ofs);
                    }
                }
                return true;
            }
        }

    }
}
原文地址:https://www.cnblogs.com/cfas/p/3172955.html