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;
}
}