using System;
using System.Net;
namespace ProtoDataBuff
{
//常量数据
public class Constants
{
//消息:数据总长度(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;
//public UInt32 TS;
public eProtocalCommand _protocallType;
public byte[] _data;
///
/// 网络结构转数据
///
///
///
public byte[] ToBytes()
{
byte[] _tmpBuff = new byte[PackLen];
byte[] _tmpBuffLength = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(PackLen));
byte[] _tmpDataType = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((Int16)_protocallType));
Array.Copy(_tmpBuffLength, 0, _tmpBuff, 0, Constants.HEAD_DATA_LEN); //缓存总长度
Array.Copy(_tmpDataType, 0, _tmpBuff, Constants.HEAD_DATA_LEN, Constants.HEAD_TYPE_LEN);//协议类型
Array.Copy(_data, 0, _tmpBuff, Constants.HEAD_LEN, DataLen()); //协议数据
return _tmpBuff;
}
public int DataLen() => _data.Length;
///
/// 数据转网络结构
///
///
///
///
public static sSocketData FromBytes(eProtocalCommand _protocalType, byte[] _data)
{
sSocketData tmpSocketData = new();
tmpSocketData.PackLen = Constants.HEAD_LEN + _data.Length;
// tmpSocketData._dataLength = _data.Length;
tmpSocketData._protocallType = _protocalType;
tmpSocketData._data = _data;
return tmpSocketData;
}
}
///
/// 网络数据缓存器,//自动大小数据缓存器
///
[Serializable]
public class DataBuffer
{
private int _minBuffLen;
private byte[] _buff;
private int _curBuffPosition;
private int _buffLength = 0;
private int _dataLength;
private UInt16 _protocalType;
///
/// 构造函数
///
/// 最小缓冲区大小
public DataBuffer(int _minBuffLen = 1024)
{
if (_minBuffLen <= 0)
{
this._minBuffLen = 1024;
}
else
{
this._minBuffLen = _minBuffLen;
}
_buff = new byte[this._minBuffLen];
}
///
/// 添加缓存数据
///
///
///
public void AddBuffer(byte[] _data, int _dataLen)
{
if (_dataLen > _buff.Length - _curBuffPosition)//超过当前缓存
{
byte[] _tmpBuff = new byte[_curBuffPosition + _dataLen];
Array.Copy(_buff, 0, _tmpBuff, 0, _curBuffPosition);
Array.Copy(_data, 0, _tmpBuff, _curBuffPosition, _dataLen);
_buff = _tmpBuff;
_tmpBuff = null;
}
else
{
Array.Copy(_data, 0, _buff, _curBuffPosition, _dataLen);
}
_curBuffPosition += _dataLen;//修改当前数据标记
}
///
/// 更新数据长度
///
public void UpdateDataLength()
{
if (_dataLength == 0 && _curBuffPosition >= Constants.HEAD_LEN)
{
byte[] tmpDataLen = new byte[Constants.HEAD_DATA_LEN];
Array.Copy(_buff, 0, tmpDataLen, 0, Constants.HEAD_DATA_LEN);
_buffLength =IPAddress.NetworkToHostOrder( BitConverter.ToInt32(tmpDataLen, 0));
byte[] tmpProtocalType = new byte[Constants.HEAD_TYPE_LEN];
Array.Copy(_buff, Constants.HEAD_DATA_LEN, tmpProtocalType, 0, Constants.HEAD_TYPE_LEN);
_protocalType = (ushort)IPAddress.NetworkToHostOrder( BitConverter.ToInt16(tmpProtocalType, 0));
_dataLength = _buffLength - Constants.HEAD_LEN;
}
}
///
/// 获取一条可用数据,返回值标记是否有数据
///
///
///
public bool GetData(out sSocketData _tmpSocketData)
{
_tmpSocketData = new sSocketData();
if (_buffLength <= 0)
{
UpdateDataLength();
}
if (_buffLength > 0 && _curBuffPosition >= _buffLength)
{
_tmpSocketData.PackLen = _buffLength;
//_tmpSocketData._dataLength = _dataLength;
_tmpSocketData._protocallType = (eProtocalCommand)_protocalType;
_tmpSocketData._data = new byte[_dataLength];
Array.Copy(_buff, Constants.HEAD_LEN, _tmpSocketData._data, 0, _dataLength);
_curBuffPosition -= _buffLength;
byte[] _tmpBuff = new byte[_curBuffPosition < _minBuffLen ? _minBuffLen : _curBuffPosition];
Array.Copy(_buff, _buffLength, _tmpBuff, 0, _curBuffPosition);
_buff = _tmpBuff;
_buffLength = 0;
_dataLength = 0;
_protocalType = 0;
return true;
}
return false;
}
}
}