using System.IO; using System; using System.Net; using UnityEngine; using pb = Google.Protobuf; /// /// socket通讯-常量数据 /// public class Csts { //消息:数据总长度(4byte) + 数据类型(2byte) + 数据(N byte) public static int HEAD_DATA_LEN = 4; public static int HEAD_TYPE_LEN = 2; public static int HEAD_LEN//6byte { get { return HEAD_DATA_LEN + HEAD_TYPE_LEN; } } } /// /// 网络数据结构 /// [Serializable] public struct sSocketData { /// /// 包长度 /// public Int32 PackLen { get; private set; } /// /// 消息类型 /// public eProtocalCommand ProtocallType { get; private set; } /// /// 包负载 /// public byte[] Data { get; private set; } public static sSocketData FromIMsg(eProtocalCommand _protocalType, pb.IMessage msg) { return FromBytes(_protocalType, msg.ToBytes()); } /// /// 网络结构转数据 /// /// /// public byte[] ToBytes() { var retArr = new byte[PackLen]; byte[] btsPackLen = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(PackLen)); byte[] btsPackType = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((Int16)ProtocallType)); Buffer.BlockCopy(btsPackLen, 0, retArr, 0, Csts.HEAD_DATA_LEN); //缓存总长度 Buffer.BlockCopy(btsPackType, 0, retArr, Csts.HEAD_DATA_LEN, Csts.HEAD_TYPE_LEN); //协议类型 Buffer.BlockCopy(Data, 0, retArr, Csts.HEAD_LEN, Data.Length); //协议数据 return retArr; } /// /// 数据转网络结构 /// /// /// /// public static sSocketData FromBytes(eProtocalCommand _protocalType, byte[] _data) { var tmpSocketData = new sSocketData() { PackLen = Csts.HEAD_LEN + _data.Length, ProtocallType = _protocalType, Data = _data }; return tmpSocketData; } } /// /// 网络数据缓存器,//自动大小数据缓存器 /// [Serializable] public class DataBuffer { private byte[] buff = new byte[0]; private int nextPackLen = 0; /// /// 添加缓存数据 /// /// /// public void AddBuffer(byte[] _data, int _dataLen) { var lp = buff.Length; Array.Resize(ref buff, lp + _dataLen); Buffer.BlockCopy(_data, 0, buff, lp, _dataLen); } /// /// 更新数据长度 /// public void UpdateDataLength() { if (buff.Length >= Csts.HEAD_LEN) { nextPackLen = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(buff[0..Csts.HEAD_DATA_LEN], 0)); } } /// /// 获取一条可用数据,返回值标记是否有数据 /// /// /// public bool GetData(out sSocketData SocketData) { if (nextPackLen <= 0) { UpdateDataLength(); } if (nextPackLen > 0 && buff.Length >= nextPackLen) { var _protocalType = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(buff[Csts.HEAD_DATA_LEN..Csts.HEAD_LEN], 0)); SocketData = sSocketData.FromBytes((eProtocalCommand)_protocalType, buff[Csts.HEAD_LEN..nextPackLen]); buff = buff[nextPackLen..]; nextPackLen = 0; return true; } SocketData = default; return false; } }