客户端网络库(包括.netstandard2.0)优化 消灭GC,复用ArrayPool<byte>
This commit is contained in:
parent
67f9c51d6f
commit
2eef9aa0d1
@ -1,8 +1,75 @@
|
||||
using System.Net.Sockets;
|
||||
using System.Buffers;
|
||||
using System.Net.Sockets;
|
||||
namespace HaoYueNet.ClientNetwork
|
||||
{
|
||||
public static class BytesArrayPool
|
||||
{
|
||||
public static byte[] RentBuffer(int minSize)
|
||||
{
|
||||
return ArrayPool<byte>.Shared.Rent(minSize);
|
||||
}
|
||||
|
||||
public static void ReturnBuffer(byte[] buffer)
|
||||
{
|
||||
ArrayPool<byte>.Shared.Return(buffer);
|
||||
}
|
||||
}
|
||||
public static class BaseData
|
||||
{
|
||||
|
||||
#if NETSTANDARD2_0_OR_GREATER
|
||||
static class BitConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// 将short值以小端序写入字节数组
|
||||
/// </summary>
|
||||
/// <param name="buffer">目标字节数组</param>
|
||||
/// <param name="value">要写入的short值</param>
|
||||
/// <param name="offset">写入起始位置</param>
|
||||
public static void TryWriteBytes(byte[] buffer, short value, int offset = 0)
|
||||
{
|
||||
// 小端序:低位在前,高位在后
|
||||
buffer[offset] = (byte)value; // 低位字节
|
||||
buffer[offset + 1] = (byte)(value >> 8); // 高位字节
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将ushort值以小端序写入字节数组
|
||||
/// </summary>
|
||||
public static void TryWriteBytes(byte[] buffer, ushort value, int offset = 0)
|
||||
{
|
||||
buffer[offset] = (byte)value; // 低位字节
|
||||
buffer[offset + 1] = (byte)(value >> 8); // 高位字节
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将uint值以小端序写入字节数组
|
||||
/// </summary>
|
||||
public static void TryWriteBytes(byte[] buffer, uint value, int offset = 0)
|
||||
{
|
||||
buffer[offset] = (byte)value; // 字节0 (最低位)
|
||||
buffer[offset + 1] = (byte)(value >> 8); // 字节1
|
||||
buffer[offset + 2] = (byte)(value >> 16); // 字节2
|
||||
buffer[offset + 3] = (byte)(value >> 24); // 字节3 (最高位)
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将int值以小端序写入字节数组
|
||||
/// </summary>
|
||||
public static void TryWriteBytes(byte[] buffer, int value, int offset = 0)
|
||||
{
|
||||
buffer[offset] = (byte)value; // 字节0 (最低位)
|
||||
buffer[offset + 1] = (byte)(value >> 8); // 字节1
|
||||
buffer[offset + 2] = (byte)(value >> 16); // 字节2
|
||||
buffer[offset + 3] = (byte)(value >> 24); // 字节3 (最高位)
|
||||
}
|
||||
|
||||
public static ushort ToUInt16(Span<byte> span)
|
||||
{
|
||||
return System.BitConverter.ToUInt16(span.ToArray(), 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/// <summary>
|
||||
/// 心跳包数据
|
||||
/// </summary>
|
||||
@ -16,12 +83,52 @@ namespace HaoYueNet.ClientNetwork
|
||||
}
|
||||
public static class HunterNet_S2C
|
||||
{
|
||||
const int LenghtDataLength = sizeof(UInt32);
|
||||
const int CmdDataLength = sizeof(UInt16);
|
||||
const int ErrDataLength = sizeof(UInt16);
|
||||
public static int GetAllLength(byte[] bodyData)
|
||||
{
|
||||
return CmdDataLength + ErrDataLength + LenghtDataLength + bodyData.Length;
|
||||
}
|
||||
public static int GetBodyLength(byte[] allData)
|
||||
{
|
||||
return allData.Length - CmdDataLength - ErrDataLength;
|
||||
}
|
||||
public static void SetDataToSocketAsyncEventArgs(SocketAsyncEventArgs myreadEventArgs, UInt16 CmdID, UInt16 Error, byte[] AddonBytes_Data)
|
||||
{
|
||||
myreadEventArgs.SetBuffer(CreatePkgData(CmdID, Error, AddonBytes_Data));
|
||||
int allDataLength = GetAllLength(AddonBytes_Data);
|
||||
byte[] finalData = BytesArrayPool.RentBuffer(allDataLength);
|
||||
CreatePkgData(CmdID, Error, AddonBytes_Data, ref finalData, out int usefulLenght);
|
||||
myreadEventArgs.SetBuffer(finalData, 0, usefulLenght);
|
||||
BytesArrayPool.ReturnBuffer(finalData);
|
||||
|
||||
//myreadEventArgs.SetBuffer(CreatePkgData(CmdID, Error, AddonBytes_Data));
|
||||
}
|
||||
public static byte[] CreatePkgData(UInt16 CmdID, UInt16 Error, byte[] AddonBytes_Data)
|
||||
public static void CreatePkgData(UInt16 CmdID, UInt16 Error, byte[] AddonBytes_Data, ref byte[] finalData, out int usefulLenght)
|
||||
{
|
||||
int allLength = GetAllLength(AddonBytes_Data);
|
||||
byte[] bytes_allLenght = BytesArrayPool.RentBuffer(LenghtDataLength);
|
||||
BitConverter.TryWriteBytes(bytes_allLenght, allLength);//包长度
|
||||
byte[] bytes_cmdid = BytesArrayPool.RentBuffer(CmdDataLength);
|
||||
BitConverter.TryWriteBytes(bytes_cmdid, CmdID);
|
||||
byte[] bytes_errid = BytesArrayPool.RentBuffer(ErrDataLength);
|
||||
BitConverter.TryWriteBytes(bytes_errid, Error);
|
||||
|
||||
Buffer.BlockCopy(bytes_allLenght, 0, finalData, 0, LenghtDataLength);
|
||||
//CMDID
|
||||
Buffer.BlockCopy(bytes_cmdid, 0, finalData, LenghtDataLength, CmdDataLength);
|
||||
//ErrID
|
||||
Buffer.BlockCopy(bytes_errid, 0, finalData, LenghtDataLength + CmdDataLength, ErrDataLength);
|
||||
//DATA
|
||||
Buffer.BlockCopy(AddonBytes_Data, 0, finalData, LenghtDataLength + CmdDataLength + ErrDataLength, AddonBytes_Data.Length);
|
||||
|
||||
BytesArrayPool.ReturnBuffer(bytes_allLenght);
|
||||
BytesArrayPool.ReturnBuffer(bytes_cmdid);
|
||||
BytesArrayPool.ReturnBuffer(bytes_errid);
|
||||
|
||||
usefulLenght = allLength;
|
||||
|
||||
/*
|
||||
//包长度
|
||||
int AllLenght = 4 + 2 + 2 + AddonBytes_Data.Length;
|
||||
byte[] BufferData = new byte[AllLenght];
|
||||
@ -33,7 +140,7 @@ namespace HaoYueNet.ClientNetwork
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(Error), 0, BufferData, 4 + 2, sizeof(UInt16));
|
||||
//DATA
|
||||
Buffer.BlockCopy(AddonBytes_Data, 0, BufferData, 4 + 2 + 2, AddonBytes_Data.Length);
|
||||
return BufferData;
|
||||
return BufferData;*/
|
||||
}
|
||||
public static void AnalysisPkgData(Span<byte> srcdata, out UInt16 CmdID, out UInt16 Error, out byte[] data)
|
||||
{
|
||||
@ -44,12 +151,57 @@ namespace HaoYueNet.ClientNetwork
|
||||
}
|
||||
public static class HunterNet_C2S
|
||||
{
|
||||
const int LenghtDataLength = sizeof(UInt32);
|
||||
const int CmdDataLength = sizeof(UInt16);
|
||||
public static int GetAllLengthByBody(byte[] bodyData)
|
||||
{
|
||||
return LenghtDataLength + CmdDataLength + bodyData.Length;
|
||||
}
|
||||
public static int GetAllLengthByUsedLen(int UsedLength)
|
||||
{
|
||||
return LenghtDataLength + CmdDataLength + UsedLength;
|
||||
}
|
||||
public static int GetBodyLength(byte[] allData)
|
||||
{
|
||||
return allData.Length - CmdDataLength;
|
||||
}
|
||||
|
||||
public static void SetDataToSocketAsyncEventArgs(SocketAsyncEventArgs myreadEventArgs, UInt16 CmdID, byte[] AddonBytes_Data)
|
||||
{
|
||||
myreadEventArgs.SetBuffer(CreatePkgData(CmdID, AddonBytes_Data));
|
||||
int allDataLength = GetAllLengthByBody(AddonBytes_Data);
|
||||
byte[] finalData = BytesArrayPool.RentBuffer(allDataLength);
|
||||
CreatePkgData(CmdID, AddonBytes_Data, ref finalData, out int usefulLenght);
|
||||
myreadEventArgs.SetBuffer(finalData, 0, usefulLenght);
|
||||
BytesArrayPool.ReturnBuffer(finalData);
|
||||
//myreadEventArgs.SetBuffer(CreatePkgData(CmdID, AddonBytes_Data));
|
||||
}
|
||||
public static byte[] CreatePkgData(UInt16 CmdID, byte[] AddonBytes_Data)
|
||||
|
||||
public static void CreatePkgData(UInt16 CmdID, byte[] bytesdata, ref byte[] finalData, out int usefulLenght)
|
||||
{
|
||||
CreatePkgData(CmdID, bytesdata, bytesdata.Length, ref finalData, out usefulLenght);
|
||||
}
|
||||
|
||||
public static void CreatePkgData(UInt16 CmdID, byte[] bytesdata, int bytesdata_useLenght, ref byte[] finalData, out int usefulLenght)
|
||||
{
|
||||
int allLength = GetAllLengthByUsedLen(bytesdata_useLenght);
|
||||
byte[] bytes_allLenght = BytesArrayPool.RentBuffer(LenghtDataLength);
|
||||
BitConverter.TryWriteBytes(bytes_allLenght, allLength);
|
||||
byte[] bytes_cmdid = BytesArrayPool.RentBuffer(CmdDataLength);
|
||||
BitConverter.TryWriteBytes(bytes_cmdid, CmdID);
|
||||
|
||||
//包长度
|
||||
Buffer.BlockCopy(bytes_allLenght, 0, finalData, 0, LenghtDataLength);
|
||||
//CMDID
|
||||
Buffer.BlockCopy(bytes_cmdid, 0, finalData, LenghtDataLength, CmdDataLength);
|
||||
//DATA
|
||||
Buffer.BlockCopy(bytesdata, 0, finalData, LenghtDataLength + CmdDataLength, bytesdata_useLenght);
|
||||
|
||||
BytesArrayPool.ReturnBuffer(bytes_allLenght);
|
||||
BytesArrayPool.ReturnBuffer(bytes_cmdid);
|
||||
|
||||
usefulLenght = allLength;
|
||||
|
||||
/*
|
||||
byte[] AddonBytes_CmdID = BitConverter.GetBytes(CmdID);
|
||||
int AllLenght = AddonBytes_CmdID.Length + AddonBytes_Data.Length + 4;
|
||||
//包长度
|
||||
@ -61,7 +213,7 @@ namespace HaoYueNet.ClientNetwork
|
||||
Buffer.BlockCopy(AddonBytes_CmdID, 0, BufferData, 4, AddonBytes_CmdID.Length);
|
||||
//DATA
|
||||
Buffer.BlockCopy(AddonBytes_Data, 0, BufferData, 4 + 2, AddonBytes_Data.Length);
|
||||
return BufferData;
|
||||
return BufferData;*/
|
||||
}
|
||||
|
||||
public static void AnalysisPkgData(Span<byte> srcdata, out UInt16 CmdID, out byte[] data)
|
||||
|
||||
@ -380,14 +380,14 @@ namespace HaoYueNet.ClientNetwork.IOCPMode
|
||||
long FristBeginPos = token.memoryStream.Position;
|
||||
|
||||
//从Byte池申请
|
||||
byte[] lenBytes = ArrayPool<byte>.Shared.Rent(4);
|
||||
byte[] lenBytes = BytesArrayPool.RentBuffer(4);
|
||||
|
||||
token.memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
token.memoryStream.Read(lenBytes, 0, 4);
|
||||
int packageLen = BitConverter.ToInt32(lenBytes, 0) - 4;
|
||||
|
||||
//归还byte[]
|
||||
ArrayPool<byte>.Shared.Return(lenBytes);
|
||||
BytesArrayPool.ReturnBuffer(lenBytes);
|
||||
|
||||
if (packageLen > token.memoryStream.Length - 4)
|
||||
{
|
||||
@ -396,7 +396,7 @@ namespace HaoYueNet.ClientNetwork.IOCPMode
|
||||
}
|
||||
|
||||
//申请byte池 一定要记得回收!!
|
||||
byte[] rev_fromArrayPool = ArrayPool<byte>.Shared.Rent(packageLen);
|
||||
byte[] rev_fromArrayPool = BytesArrayPool.RentBuffer(packageLen);
|
||||
|
||||
token.memoryStream.Seek(4, SeekOrigin.Begin);
|
||||
token.memoryStream.Read(rev_fromArrayPool, 0, packageLen);
|
||||
@ -416,7 +416,7 @@ namespace HaoYueNet.ClientNetwork.IOCPMode
|
||||
DataCallBackReady(token, rev_span);
|
||||
|
||||
//回收(这里依赖DataCallBackReady中,有一次数据拷贝,这个后续还要进一步精进性能优化,否则不能在这里回收,否则影响业务层)
|
||||
ArrayPool<byte>.Shared.Return(rev_fromArrayPool);
|
||||
BytesArrayPool.ReturnBuffer(rev_fromArrayPool);
|
||||
} while (token.memoryStream.Length > 4);
|
||||
}
|
||||
|
||||
|
||||
@ -108,13 +108,13 @@ namespace HaoYueNet.ClientNetwork
|
||||
client.Close();
|
||||
}
|
||||
|
||||
private void SendToSocket(byte[] data)
|
||||
private void SendToSocket(byte[] data, int usefulLenght)
|
||||
{
|
||||
//已拼接包长度,这里不再需要拼接长度
|
||||
//data = SendDataWithHead(data);
|
||||
try
|
||||
{
|
||||
SendWithIndex(data);
|
||||
SendWithIndex(data, usefulLenght);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -129,7 +129,7 @@ namespace HaoYueNet.ClientNetwork
|
||||
{
|
||||
try
|
||||
{
|
||||
SendWithIndex(HeartbeatData);
|
||||
SendWithIndex(HeartbeatData, HeartbeatData.Length);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -145,14 +145,14 @@ namespace HaoYueNet.ClientNetwork
|
||||
/// 发送数据并计数
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
private void SendWithIndex(byte[] data)
|
||||
private void SendWithIndex(byte[] data, int usefulLenght)
|
||||
{
|
||||
lock (sendLock)
|
||||
{
|
||||
//增加发送计数
|
||||
SendIndex = MaxSendIndexNum;
|
||||
//发送数据
|
||||
client.Send(data);
|
||||
client.Send(data, usefulLenght, SocketFlags.None);
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,10 +161,32 @@ namespace HaoYueNet.ClientNetwork
|
||||
/// </summary>
|
||||
/// <param name="CMDID"></param>
|
||||
/// <param name="data">序列化之后的数据</param>
|
||||
public void SendToServer(int CMDID,byte[] data)
|
||||
public virtual void SendToServer(int CmdID, byte[] data)
|
||||
{
|
||||
byte[] _finaldata = HunterNet_C2S.CreatePkgData((ushort)CMDID, data);
|
||||
SendToSocket(_finaldata);
|
||||
SendToServerWithLength(CmdID, ref data, data.Length);
|
||||
|
||||
//int allDataLength = HunterNet_C2S.GetAllLengthByBody(data);
|
||||
//byte[] _finaldata = BytesArrayPool.RentBuffer(allDataLength);
|
||||
//HunterNet_C2S.CreatePkgData((ushort)CmdID, data, ref _finaldata, out int usefulLenght);
|
||||
//SendToSocket(_finaldata, usefulLenght);
|
||||
//BytesArrayPool.ReturnBuffer(_finaldata);
|
||||
|
||||
//byte[] _finaldata = HunterNet_C2S.CreatePkgData((ushort)CmdID, data);
|
||||
//SendToSocket(_finaldata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 供外部调用 发送消息
|
||||
/// </summary>
|
||||
/// <param name="CMDID"></param>
|
||||
/// <param name="data">序列化之后的数据</param>
|
||||
public virtual void SendToServerWithLength(int CmdID, ref byte[] data, int len)
|
||||
{
|
||||
int allDataLength = HunterNet_C2S.GetAllLengthByUsedLen(len);
|
||||
byte[] _finaldata = BytesArrayPool.RentBuffer(allDataLength);
|
||||
HunterNet_C2S.CreatePkgData((ushort)CmdID, data, len, ref _finaldata, out int usefulLenght);
|
||||
SendToSocket(_finaldata, usefulLenght);
|
||||
BytesArrayPool.ReturnBuffer(_finaldata);
|
||||
}
|
||||
|
||||
#region 事件定义
|
||||
|
||||
@ -78,13 +78,13 @@ namespace HaoYueNet.ClientNetwork
|
||||
client.Close();
|
||||
}
|
||||
|
||||
private void SendToSocket(byte[] data)
|
||||
private void SendToSocket(byte[] data, int usefulLenght)
|
||||
{
|
||||
//已拼接包长度,这里不再需要拼接长度
|
||||
//data = SendDataWithHead(data);
|
||||
try
|
||||
{
|
||||
SendWithIndex(data);
|
||||
SendWithIndex(data, usefulLenght);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -99,7 +99,7 @@ namespace HaoYueNet.ClientNetwork
|
||||
{
|
||||
try
|
||||
{
|
||||
SendWithIndex(BaseData.HeartbeatData);
|
||||
SendWithIndex(BaseData.HeartbeatData, BaseData.HeartbeatData.Length);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -114,12 +114,12 @@ namespace HaoYueNet.ClientNetwork
|
||||
/// 发送数据并计数
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
private void SendWithIndex(byte[] data)
|
||||
private void SendWithIndex(byte[] data, int usefulLenght)
|
||||
{
|
||||
//增加发送计数
|
||||
SendIndex = MaxSendIndexNum;
|
||||
//发送数据
|
||||
client.Send(data);
|
||||
client.Send(data, usefulLenght, SocketFlags.None);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -130,8 +130,15 @@ namespace HaoYueNet.ClientNetwork
|
||||
/// <param name="data"></param>
|
||||
public void SendToSocket(int CMDID, int ERRCODE, byte[] data)
|
||||
{
|
||||
byte[] _finaldata = HunterNet_S2C.CreatePkgData((ushort)CMDID, (ushort)ERRCODE, data);
|
||||
SendToSocket(_finaldata);
|
||||
|
||||
int allDataLength = HunterNet_C2S.GetAllLengthByBody(data);
|
||||
byte[] _finaldata = BytesArrayPool.RentBuffer(allDataLength);
|
||||
HunterNet_S2C.CreatePkgData((ushort)CMDID, (ushort)ERRCODE, data, ref _finaldata, out int usefulLenght);
|
||||
SendToSocket(_finaldata, usefulLenght);
|
||||
BytesArrayPool.ReturnBuffer(_finaldata);
|
||||
|
||||
//byte[] _finaldata = HunterNet_S2C.CreatePkgData((ushort)CMDID, (ushort)ERRCODE, data);
|
||||
//SendToSocket(_finaldata);
|
||||
}
|
||||
|
||||
public delegate void OnDataCallBack_Data(int CMDID, int ERRCODE, byte[] data);
|
||||
|
||||
@ -199,7 +199,7 @@ namespace HaoYueNet.ClientNetwork.OtherMode
|
||||
while (true)
|
||||
{
|
||||
//申请byte池 一定要记得回收!!
|
||||
byte[] rev_fromArrayPool = ArrayPool<byte>.Shared.Rent(1024 * 1024 * 2);
|
||||
byte[] rev_fromArrayPool = BytesArrayPool.RentBuffer(1024 * 1024 * 2);
|
||||
|
||||
int effective = 0;
|
||||
try
|
||||
@ -213,7 +213,7 @@ namespace HaoYueNet.ClientNetwork.OtherMode
|
||||
//远程主机强迫关闭了一个现有的连接
|
||||
OnCloseReady(client);
|
||||
//回收
|
||||
ArrayPool<byte>.Shared.Return(rev_fromArrayPool);
|
||||
BytesArrayPool.ReturnBuffer(rev_fromArrayPool);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -232,7 +232,7 @@ namespace HaoYueNet.ClientNetwork.OtherMode
|
||||
reciveMemoryStream.Write(rev_fromArrayPool, 0, effective);//将接受到的数据写入内存流中
|
||||
|
||||
//回收
|
||||
ArrayPool<byte>.Shared.Return(rev_fromArrayPool);
|
||||
BytesArrayPool.ReturnBuffer(rev_fromArrayPool);
|
||||
|
||||
DataCallBackReady(client, reciveMemoryStream.ToArray());
|
||||
//流复用的方式 不用重新new申请
|
||||
|
||||
@ -1,9 +1,76 @@
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Net.Sockets;
|
||||
namespace HaoYueNet.ClientNetwork
|
||||
{
|
||||
public static class BytesArrayPool
|
||||
{
|
||||
public static byte[] RentBuffer(int minSize)
|
||||
{
|
||||
return ArrayPool<byte>.Shared.Rent(minSize);
|
||||
}
|
||||
|
||||
public static void ReturnBuffer(byte[] buffer)
|
||||
{
|
||||
ArrayPool<byte>.Shared.Return(buffer);
|
||||
}
|
||||
}
|
||||
public static class BaseData
|
||||
{
|
||||
|
||||
#if NETSTANDARD2_0_OR_GREATER
|
||||
static class BitConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// 将short值以小端序写入字节数组
|
||||
/// </summary>
|
||||
/// <param name="buffer">目标字节数组</param>
|
||||
/// <param name="value">要写入的short值</param>
|
||||
/// <param name="offset">写入起始位置</param>
|
||||
public static void TryWriteBytes(byte[] buffer, short value, int offset = 0)
|
||||
{
|
||||
// 小端序:低位在前,高位在后
|
||||
buffer[offset] = (byte)value; // 低位字节
|
||||
buffer[offset + 1] = (byte)(value >> 8); // 高位字节
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将ushort值以小端序写入字节数组
|
||||
/// </summary>
|
||||
public static void TryWriteBytes(byte[] buffer, ushort value, int offset = 0)
|
||||
{
|
||||
buffer[offset] = (byte)value; // 低位字节
|
||||
buffer[offset + 1] = (byte)(value >> 8); // 高位字节
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将uint值以小端序写入字节数组
|
||||
/// </summary>
|
||||
public static void TryWriteBytes(byte[] buffer, uint value, int offset = 0)
|
||||
{
|
||||
buffer[offset] = (byte)value; // 字节0 (最低位)
|
||||
buffer[offset + 1] = (byte)(value >> 8); // 字节1
|
||||
buffer[offset + 2] = (byte)(value >> 16); // 字节2
|
||||
buffer[offset + 3] = (byte)(value >> 24); // 字节3 (最高位)
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将int值以小端序写入字节数组
|
||||
/// </summary>
|
||||
public static void TryWriteBytes(byte[] buffer, int value, int offset = 0)
|
||||
{
|
||||
buffer[offset] = (byte)value; // 字节0 (最低位)
|
||||
buffer[offset + 1] = (byte)(value >> 8); // 字节1
|
||||
buffer[offset + 2] = (byte)(value >> 16); // 字节2
|
||||
buffer[offset + 3] = (byte)(value >> 24); // 字节3 (最高位)
|
||||
}
|
||||
|
||||
public static ushort ToUInt16(Span<byte> span)
|
||||
{
|
||||
return System.BitConverter.ToUInt16(span.ToArray(), 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/// <summary>
|
||||
/// 心跳包数据
|
||||
/// </summary>
|
||||
@ -17,13 +84,52 @@ namespace HaoYueNet.ClientNetwork
|
||||
}
|
||||
public static class HunterNet_S2C
|
||||
{
|
||||
const int LenghtDataLength = sizeof(UInt32);
|
||||
const int CmdDataLength = sizeof(UInt16);
|
||||
const int ErrDataLength = sizeof(UInt16);
|
||||
public static int GetAllLength(byte[] bodyData)
|
||||
{
|
||||
return CmdDataLength + ErrDataLength + LenghtDataLength + bodyData.Length;
|
||||
}
|
||||
public static int GetBodyLength(byte[] allData)
|
||||
{
|
||||
return allData.Length - CmdDataLength - ErrDataLength;
|
||||
}
|
||||
public static void SetDataToSocketAsyncEventArgs(SocketAsyncEventArgs myreadEventArgs, UInt16 CmdID, UInt16 Error, byte[] AddonBytes_Data)
|
||||
{
|
||||
byte[] data = CreatePkgData(CmdID, Error, AddonBytes_Data);
|
||||
myreadEventArgs.SetBuffer(data,0,data.Length);
|
||||
int allDataLength = GetAllLength(AddonBytes_Data);
|
||||
byte[] finalData = BytesArrayPool.RentBuffer(allDataLength);
|
||||
CreatePkgData(CmdID, Error, AddonBytes_Data, ref finalData, out int usefulLenght);
|
||||
myreadEventArgs.SetBuffer(finalData, 0, usefulLenght);
|
||||
BytesArrayPool.ReturnBuffer(finalData);
|
||||
|
||||
//myreadEventArgs.SetBuffer(CreatePkgData(CmdID, Error, AddonBytes_Data));
|
||||
}
|
||||
public static byte[] CreatePkgData(UInt16 CmdID, UInt16 Error, byte[] AddonBytes_Data)
|
||||
public static void CreatePkgData(UInt16 CmdID, UInt16 Error, byte[] AddonBytes_Data, ref byte[] finalData, out int usefulLenght)
|
||||
{
|
||||
int allLength = GetAllLength(AddonBytes_Data);
|
||||
byte[] bytes_allLenght = BytesArrayPool.RentBuffer(LenghtDataLength);
|
||||
BitConverter.TryWriteBytes(bytes_allLenght, allLength);//包长度
|
||||
byte[] bytes_cmdid = BytesArrayPool.RentBuffer(CmdDataLength);
|
||||
BitConverter.TryWriteBytes(bytes_cmdid, CmdID);
|
||||
byte[] bytes_errid = BytesArrayPool.RentBuffer(ErrDataLength);
|
||||
BitConverter.TryWriteBytes(bytes_errid, Error);
|
||||
|
||||
Buffer.BlockCopy(bytes_allLenght, 0, finalData, 0, LenghtDataLength);
|
||||
//CMDID
|
||||
Buffer.BlockCopy(bytes_cmdid, 0, finalData, LenghtDataLength, CmdDataLength);
|
||||
//ErrID
|
||||
Buffer.BlockCopy(bytes_errid, 0, finalData, LenghtDataLength + CmdDataLength, ErrDataLength);
|
||||
//DATA
|
||||
Buffer.BlockCopy(AddonBytes_Data, 0, finalData, LenghtDataLength + CmdDataLength + ErrDataLength, AddonBytes_Data.Length);
|
||||
|
||||
BytesArrayPool.ReturnBuffer(bytes_allLenght);
|
||||
BytesArrayPool.ReturnBuffer(bytes_cmdid);
|
||||
BytesArrayPool.ReturnBuffer(bytes_errid);
|
||||
|
||||
usefulLenght = allLength;
|
||||
|
||||
/*
|
||||
//包长度
|
||||
int AllLenght = 4 + 2 + 2 + AddonBytes_Data.Length;
|
||||
byte[] BufferData = new byte[AllLenght];
|
||||
@ -35,24 +141,68 @@ namespace HaoYueNet.ClientNetwork
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(Error), 0, BufferData, 4 + 2, sizeof(UInt16));
|
||||
//DATA
|
||||
Buffer.BlockCopy(AddonBytes_Data, 0, BufferData, 4 + 2 + 2, AddonBytes_Data.Length);
|
||||
return BufferData;
|
||||
return BufferData;*/
|
||||
}
|
||||
public static void AnalysisPkgData(Span<byte> srcdata, out UInt16 CmdID, out UInt16 Error, out byte[] data)
|
||||
{
|
||||
CmdID = BitConverter.ToUInt16(srcdata.Slice(0, 2).ToArray(), 0);
|
||||
Error = BitConverter.ToUInt16(srcdata.Slice(2, 2).ToArray(), 0);
|
||||
CmdID = BitConverter.ToUInt16(srcdata.Slice(0, 2));
|
||||
Error = BitConverter.ToUInt16(srcdata.Slice(2, 2));
|
||||
data = srcdata.Slice(2 + 2).ToArray();
|
||||
}
|
||||
}
|
||||
public static class HunterNet_C2S
|
||||
{
|
||||
const int LenghtDataLength = sizeof(UInt32);
|
||||
const int CmdDataLength = sizeof(UInt16);
|
||||
public static int GetAllLengthByBody(byte[] bodyData)
|
||||
{
|
||||
return LenghtDataLength + CmdDataLength + bodyData.Length;
|
||||
}
|
||||
public static int GetAllLengthByUsedLen(int UsedLength)
|
||||
{
|
||||
return LenghtDataLength + CmdDataLength + UsedLength;
|
||||
}
|
||||
public static int GetBodyLength(byte[] allData)
|
||||
{
|
||||
return allData.Length - CmdDataLength;
|
||||
}
|
||||
|
||||
public static void SetDataToSocketAsyncEventArgs(SocketAsyncEventArgs myreadEventArgs, UInt16 CmdID, byte[] AddonBytes_Data)
|
||||
{
|
||||
byte[] data = CreatePkgData(CmdID, AddonBytes_Data);
|
||||
myreadEventArgs.SetBuffer(data, 0, data.Length);
|
||||
int allDataLength = GetAllLengthByBody(AddonBytes_Data);
|
||||
byte[] finalData = BytesArrayPool.RentBuffer(allDataLength);
|
||||
CreatePkgData(CmdID, AddonBytes_Data, ref finalData, out int usefulLenght);
|
||||
myreadEventArgs.SetBuffer(finalData, 0, usefulLenght);
|
||||
BytesArrayPool.ReturnBuffer(finalData);
|
||||
//myreadEventArgs.SetBuffer(CreatePkgData(CmdID, AddonBytes_Data));
|
||||
}
|
||||
public static byte[] CreatePkgData(UInt16 CmdID, byte[] AddonBytes_Data)
|
||||
|
||||
public static void CreatePkgData(UInt16 CmdID, byte[] bytesdata, ref byte[] finalData, out int usefulLenght)
|
||||
{
|
||||
CreatePkgData(CmdID, bytesdata, bytesdata.Length, ref finalData, out usefulLenght);
|
||||
}
|
||||
|
||||
public static void CreatePkgData(UInt16 CmdID, byte[] bytesdata,int bytesdata_useLenght, ref byte[] finalData, out int usefulLenght)
|
||||
{
|
||||
int allLength = GetAllLengthByUsedLen(bytesdata_useLenght);
|
||||
byte[] bytes_allLenght = BytesArrayPool.RentBuffer(LenghtDataLength);
|
||||
BitConverter.TryWriteBytes(bytes_allLenght, allLength);
|
||||
byte[] bytes_cmdid = BytesArrayPool.RentBuffer(CmdDataLength);
|
||||
BitConverter.TryWriteBytes(bytes_cmdid, CmdID);
|
||||
|
||||
//包长度
|
||||
Buffer.BlockCopy(bytes_allLenght, 0, finalData, 0, LenghtDataLength);
|
||||
//CMDID
|
||||
Buffer.BlockCopy(bytes_cmdid, 0, finalData, LenghtDataLength, CmdDataLength);
|
||||
//DATA
|
||||
Buffer.BlockCopy(bytesdata, 0, finalData, LenghtDataLength + CmdDataLength, bytesdata_useLenght);
|
||||
|
||||
BytesArrayPool.ReturnBuffer(bytes_allLenght);
|
||||
BytesArrayPool.ReturnBuffer(bytes_cmdid);
|
||||
|
||||
usefulLenght = allLength;
|
||||
|
||||
/*
|
||||
byte[] AddonBytes_CmdID = BitConverter.GetBytes(CmdID);
|
||||
int AllLenght = AddonBytes_CmdID.Length + AddonBytes_Data.Length + 4;
|
||||
//包长度
|
||||
@ -64,12 +214,12 @@ namespace HaoYueNet.ClientNetwork
|
||||
Buffer.BlockCopy(AddonBytes_CmdID, 0, BufferData, 4, AddonBytes_CmdID.Length);
|
||||
//DATA
|
||||
Buffer.BlockCopy(AddonBytes_Data, 0, BufferData, 4 + 2, AddonBytes_Data.Length);
|
||||
return BufferData;
|
||||
return BufferData;*/
|
||||
}
|
||||
|
||||
public static void AnalysisPkgData(Span<byte> srcdata, out UInt16 CmdID, out byte[] data)
|
||||
{
|
||||
CmdID = BitConverter.ToUInt16(srcdata.Slice(0, 2).ToArray(),0);
|
||||
CmdID = BitConverter.ToUInt16(srcdata.Slice(0, 2));
|
||||
data = srcdata.Slice(2).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
@ -383,14 +383,14 @@ namespace HaoYueNet.ClientNetwork.IOCPMode
|
||||
long FristBeginPos = token.memoryStream.Position;
|
||||
|
||||
//从Byte池申请
|
||||
byte[] lenBytes = ArrayPool<byte>.Shared.Rent(4);
|
||||
byte[] lenBytes = BytesArrayPool.RentBuffer(4);
|
||||
|
||||
token.memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
token.memoryStream.Read(lenBytes, 0, 4);
|
||||
int packageLen = BitConverter.ToInt32(lenBytes, 0) - 4;
|
||||
|
||||
//归还byte[]
|
||||
ArrayPool<byte>.Shared.Return(lenBytes);
|
||||
BytesArrayPool.ReturnBuffer(lenBytes);
|
||||
|
||||
if (packageLen > token.memoryStream.Length - 4)
|
||||
{
|
||||
@ -399,7 +399,7 @@ namespace HaoYueNet.ClientNetwork.IOCPMode
|
||||
}
|
||||
|
||||
//申请byte池 一定要记得回收!!
|
||||
byte[] rev_fromArrayPool = ArrayPool<byte>.Shared.Rent(packageLen);
|
||||
byte[] rev_fromArrayPool = BytesArrayPool.RentBuffer(packageLen);
|
||||
|
||||
token.memoryStream.Seek(4, SeekOrigin.Begin);
|
||||
token.memoryStream.Read(rev_fromArrayPool, 0, packageLen);
|
||||
@ -419,7 +419,7 @@ namespace HaoYueNet.ClientNetwork.IOCPMode
|
||||
DataCallBackReady(token, rev_span);
|
||||
|
||||
//回收(这里依赖DataCallBackReady中,有一次数据拷贝,这个后续还要进一步精进性能优化,否则不能在这里回收,否则影响业务层)
|
||||
ArrayPool<byte>.Shared.Return(rev_fromArrayPool);
|
||||
BytesArrayPool.ReturnBuffer(rev_fromArrayPool);
|
||||
} while (token.memoryStream.Length > 4);
|
||||
}
|
||||
|
||||
|
||||
@ -111,13 +111,13 @@ namespace HaoYueNet.ClientNetwork
|
||||
client.Close();
|
||||
}
|
||||
|
||||
private void SendToSocket(byte[] data)
|
||||
private void SendToSocket(byte[] data, int usefulLenght)
|
||||
{
|
||||
//已拼接包长度,这里不再需要拼接长度
|
||||
//data = SendDataWithHead(data);
|
||||
try
|
||||
{
|
||||
SendWithIndex(data);
|
||||
SendWithIndex(data, usefulLenght);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -132,7 +132,7 @@ namespace HaoYueNet.ClientNetwork
|
||||
{
|
||||
try
|
||||
{
|
||||
SendWithIndex(HeartbeatData);
|
||||
SendWithIndex(HeartbeatData, HeartbeatData.Length);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -148,14 +148,14 @@ namespace HaoYueNet.ClientNetwork
|
||||
/// 发送数据并计数
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
private void SendWithIndex(byte[] data)
|
||||
private void SendWithIndex(byte[] data, int usefulLenght)
|
||||
{
|
||||
lock (sendLock)
|
||||
{
|
||||
//增加发送计数
|
||||
SendIndex = MaxSendIndexNum;
|
||||
//发送数据
|
||||
client.Send(data);
|
||||
client.Send(data, usefulLenght, SocketFlags.None);
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,12 +164,33 @@ namespace HaoYueNet.ClientNetwork
|
||||
/// </summary>
|
||||
/// <param name="CMDID"></param>
|
||||
/// <param name="data">序列化之后的数据</param>
|
||||
public void SendToServer(int CMDID,byte[] data)
|
||||
public virtual void SendToServer(int CmdID, byte[] data)
|
||||
{
|
||||
byte[] _finaldata = HunterNet_C2S.CreatePkgData((ushort)CMDID, data);
|
||||
SendToSocket(_finaldata);
|
||||
SendToServerWithLength(CmdID, ref data, data.Length);
|
||||
|
||||
//int allDataLength = HunterNet_C2S.GetAllLengthByBody(data);
|
||||
//byte[] _finaldata = BytesArrayPool.RentBuffer(allDataLength);
|
||||
//HunterNet_C2S.CreatePkgData((ushort)CmdID, data, ref _finaldata, out int usefulLenght);
|
||||
//SendToSocket(_finaldata, usefulLenght);
|
||||
//BytesArrayPool.ReturnBuffer(_finaldata);
|
||||
|
||||
//byte[] _finaldata = HunterNet_C2S.CreatePkgData((ushort)CmdID, data);
|
||||
//SendToSocket(_finaldata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 供外部调用 发送消息
|
||||
/// </summary>
|
||||
/// <param name="CMDID"></param>
|
||||
/// <param name="data">序列化之后的数据</param>
|
||||
public virtual void SendToServerWithLength(int CmdID, ref byte[] data, int len)
|
||||
{
|
||||
int allDataLength = HunterNet_C2S.GetAllLengthByUsedLen(len);
|
||||
byte[] _finaldata = BytesArrayPool.RentBuffer(allDataLength);
|
||||
HunterNet_C2S.CreatePkgData((ushort)CmdID, data, len, ref _finaldata, out int usefulLenght);
|
||||
SendToSocket(_finaldata, usefulLenght);
|
||||
BytesArrayPool.ReturnBuffer(_finaldata);
|
||||
}
|
||||
#region 事件定义
|
||||
public delegate void OnReceiveDataHandler(int CMDID, int ERRCODE, byte[] data);
|
||||
public delegate void OnConnectedHandler(bool IsConnected);
|
||||
|
||||
@ -81,13 +81,13 @@ namespace HaoYueNet.ClientNetwork
|
||||
client.Close();
|
||||
}
|
||||
|
||||
private void SendToSocket(byte[] data)
|
||||
private void SendToSocket(byte[] data, int usefulLenght)
|
||||
{
|
||||
//已拼接包长度,这里不再需要拼接长度
|
||||
//data = SendDataWithHead(data);
|
||||
try
|
||||
{
|
||||
SendWithIndex(data);
|
||||
SendWithIndex(data, usefulLenght);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -102,7 +102,7 @@ namespace HaoYueNet.ClientNetwork
|
||||
{
|
||||
try
|
||||
{
|
||||
SendWithIndex(BaseData.HeartbeatData);
|
||||
SendWithIndex(BaseData.HeartbeatData, BaseData.HeartbeatData.Length);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -117,12 +117,12 @@ namespace HaoYueNet.ClientNetwork
|
||||
/// 发送数据并计数
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
private void SendWithIndex(byte[] data)
|
||||
private void SendWithIndex(byte[] data, int usefulLenght)
|
||||
{
|
||||
//增加发送计数
|
||||
SendIndex = MaxSendIndexNum;
|
||||
//发送数据
|
||||
client.Send(data);
|
||||
client.Send(data, usefulLenght, SocketFlags.None);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -133,8 +133,15 @@ namespace HaoYueNet.ClientNetwork
|
||||
/// <param name="data"></param>
|
||||
public void SendToSocket(int CMDID, int ERRCODE, byte[] data)
|
||||
{
|
||||
byte[] _finaldata = HunterNet_S2C.CreatePkgData((ushort)CMDID, (ushort)ERRCODE, data);
|
||||
SendToSocket(_finaldata);
|
||||
|
||||
int allDataLength = HunterNet_C2S.GetAllLengthByBody(data);
|
||||
byte[] _finaldata = BytesArrayPool.RentBuffer(allDataLength);
|
||||
HunterNet_S2C.CreatePkgData((ushort)CMDID, (ushort)ERRCODE, data, ref _finaldata, out int usefulLenght);
|
||||
SendToSocket(_finaldata, usefulLenght);
|
||||
BytesArrayPool.ReturnBuffer(_finaldata);
|
||||
|
||||
//byte[] _finaldata = HunterNet_S2C.CreatePkgData((ushort)CMDID, (ushort)ERRCODE, data);
|
||||
//SendToSocket(_finaldata);
|
||||
}
|
||||
|
||||
public delegate void OnDataCallBack_Data(int CMDID, int ERRCODE, byte[] data);
|
||||
|
||||
@ -205,7 +205,7 @@ namespace HaoYueNet.ClientNetwork.OtherMode
|
||||
while (true)
|
||||
{
|
||||
//申请byte池 一定要记得回收!!
|
||||
byte[] rev_fromArrayPool = ArrayPool<byte>.Shared.Rent(1024 * 1024 * 2);
|
||||
byte[] rev_fromArrayPool = BytesArrayPool.RentBuffer(1024 * 1024 * 2);
|
||||
|
||||
int effective = 0;
|
||||
try
|
||||
@ -219,7 +219,7 @@ namespace HaoYueNet.ClientNetwork.OtherMode
|
||||
//远程主机强迫关闭了一个现有的连接
|
||||
OnCloseReady(client);
|
||||
//回收
|
||||
ArrayPool<byte>.Shared.Return(rev_fromArrayPool);
|
||||
BytesArrayPool.ReturnBuffer(rev_fromArrayPool);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -238,7 +238,7 @@ namespace HaoYueNet.ClientNetwork.OtherMode
|
||||
reciveMemoryStream.Write(rev_fromArrayPool, 0, effective);//将接受到的数据写入内存流中
|
||||
|
||||
//回收
|
||||
ArrayPool<byte>.Shared.Return(rev_fromArrayPool);
|
||||
BytesArrayPool.ReturnBuffer(rev_fromArrayPool);
|
||||
|
||||
DataCallBackReady(client, reciveMemoryStream.ToArray());
|
||||
//流复用的方式 不用重新new申请
|
||||
|
||||
Loading…
Reference in New Issue
Block a user