游戏开发之网络篇_07 Socket中收发数据内容

26 篇文章 1 订阅
10 篇文章 0 订阅

前面其实除了我们使用protobuf来使用作为传输消息的内容外,我们之前读取消息已经接收消息都没有一个准备的类来帮助我们处理消息,这个类的作用就是来帮助我们收发消息以及后面我们要用的消息的编码和消息的解码使用的.
看一下前面的代码我们接收到服务器消息的时候都是简单粗暴的new出一个byte[]字节数组来接收服务器发送过来的数据,这样不方便大型项目的后期管理和维护,设计模式中也讲到类的单一职责嘛,那么我们现在就准备一个类专门类负责数据的收发内容.

using System;

public class ByteArray
    {
        /// <summary>
        /// 默认大小
        /// </summary>
        private const int DEFAULT_SIZE = 1024;

        /// <summary>
        /// 初始大小
        /// </summary>
        private int initSize = 0;


        /// <summary>
        /// 缓冲区
        /// </summary>
        public byte[] bytes;

        /// <summary>
        /// 读取位置
        /// </summary>
        /// <returns></returns>
        public int readInx = 0;

        /// <summary>
        /// 写入的位置
        /// </summary>
        public int writeInx = 0;

        /// <summary>
        /// 容量
        /// </summary>
        public int capacity = 0;

        /// <summary>
        /// 剩余空间
        /// </summary>
        public int remain
        {
            get { return capacity - writeInx; }
        }

        /// <summary>
        /// 数据长度
        /// </summary>
        public int Length
        {
            get { return writeInx - readInx; }
        }

        public ByteArray(byte[] defaultBytes)
        {
            bytes = defaultBytes;
            capacity = defaultBytes.Length;
            initSize = defaultBytes.Length;
            readInx = 0;
            writeInx = defaultBytes.Length;
        }

        public ByteArray(int size = DEFAULT_SIZE)
        {
            bytes = new byte[size];
            capacity = size;
            initSize = size;
            readInx = 0;
            writeInx = 0;
        }

        /// <summary>
        /// 动态扩容
        /// </summary>
        /// <param name="size">所需要的数据长度</param>
        public void ReSize(int size)
        {
            if (size < Length) return;
            if (size < initSize) return;
            int n = 1;
            while (n < size)
            {
                n *= 2;
            }

            capacity = n;
            byte[] newBytes = new byte[capacity];
            Array.Copy(bytes, readInx, newBytes, 0, writeInx - readInx);
            bytes = newBytes;
            writeInx = Length;
            readInx = 0;
        }

        /// <summary>
        /// 检查并移动数据
        /// </summary>
        public void CheckAndMoveBytes()
        {
            if (Length < 8)
            {
                MoveBytes();
            }
        }

        /// <summary>
        /// 具体的移动数据
        /// </summary>
        public void MoveBytes()
        {
            //原数组,源数组的起始位置,目标数组,目标数组的起始位置,要复制的消息长度
            Array.Copy(bytes, readInx, bytes, 0, Length);
            writeInx = Length;
            readInx = 0;
        }

        /// <summary>
        /// 写入数据
        /// </summary>
        /// <param name="bs"></param>
        /// <param name="offset"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public int Write(byte[] bs, int offset, int count)
        {
            if (remain < count)
            {
                ReSize(Length + count);
            }

            Array.Copy(bs, offset, bytes, writeInx, count);
            writeInx += count;
            return count;
        }

        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="bs"></param>
        /// <param name="offset"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public int Read(byte[] bs, int offset, int count)
        {
            count = Math.Min(count, Length);
            Array.Copy(bytes, readInx, bs, offset, count);
            readInx += count;
            CheckAndMoveBytes();
            return count;
        }

        /// <summary>
        /// 读取Int16
        /// </summary>
        /// <returns></returns>
        public Int16 ReadInt16()
        {
            if (Length < 2) return 0;
            Int16 ret = (Int16) ((bytes[1] << 8) | bytes[0]);
            readInx += 2;
            CheckAndMoveBytes();
            return ret;
        }

        /// <summary>
        /// 读取Int32
        /// </summary>
        /// <returns></returns>
        public Int32 ReadInt32()
        {
            if (Length < 4) return 0;
            Int32 ret = (Int32) ((bytes[3] << 24) |
                                 (bytes[2] << 16) |
                                 (bytes[1] << 8) |
                                 bytes[0]);

            readInx += 4;
            CheckAndMoveBytes();

            return ret;
        }

        /// <summary>
        /// 打印缓冲区(仅为调试)
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return BitConverter.ToString(bytes, readInx, Length);
        }

        /// <summary>
        /// 打印调试信息(仅为调试)
        /// </summary>
        /// <returns></returns>
        public string Debug()
        {
            return string.Format("readIdx({0}) writeIdx({1}) bytes({2})", readInx, writeInx,
                BitConverter.ToString(bytes, 0, bytes.Length));
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值