From 2eef9aa0d1dfc92ff7468cb07629d05df79ef34a Mon Sep 17 00:00:00 2001 From: sin365 <353374337@qq.com> Date: Thu, 6 Nov 2025 15:51:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=A2=E6=88=B7=E7=AB=AF=E7=BD=91=E7=BB=9C?= =?UTF-8?q?=E5=BA=93=EF=BC=88=E5=8C=85=E6=8B=AC.netstandard2.0=EF=BC=89?= =?UTF-8?q?=E4=BC=98=E5=8C=96=20=E6=B6=88=E7=81=ADGC=EF=BC=8C=E5=A4=8D?= =?UTF-8?q?=E7=94=A8ArrayPool?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NetLib/HaoYueNet.ClientNetwork/BaseData.cs | 168 ++++++++++++++++- .../IOCPMode/TcpSaeaClient.cs | 8 +- .../NetworkHelperCore.cs | 52 ++++-- .../NetworkHelperP2PCore.cs | 31 ++-- .../NetworkHelperCore_ListenerMode.cs | 6 +- .../BaseData.cs | 172 ++++++++++++++++-- .../IOCPMode/TcpSaeaClient.cs | 8 +- .../NetworkHelperCore.cs | 51 ++++-- .../NetworkHelperP2PCore.cs | 31 ++-- .../NetworkHelperCore_ListenerMode.cs | 6 +- 10 files changed, 446 insertions(+), 87 deletions(-) diff --git a/NetLib/HaoYueNet.ClientNetwork/BaseData.cs b/NetLib/HaoYueNet.ClientNetwork/BaseData.cs index 9a1e53c..dbcae74 100644 --- a/NetLib/HaoYueNet.ClientNetwork/BaseData.cs +++ b/NetLib/HaoYueNet.ClientNetwork/BaseData.cs @@ -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.Shared.Rent(minSize); + } + + public static void ReturnBuffer(byte[] buffer) + { + ArrayPool.Shared.Return(buffer); + } + } public static class BaseData { + +#if NETSTANDARD2_0_OR_GREATER + static class BitConverter + { + /// + /// 将short值以小端序写入字节数组 + /// + /// 目标字节数组 + /// 要写入的short值 + /// 写入起始位置 + public static void TryWriteBytes(byte[] buffer, short value, int offset = 0) + { + // 小端序:低位在前,高位在后 + buffer[offset] = (byte)value; // 低位字节 + buffer[offset + 1] = (byte)(value >> 8); // 高位字节 + } + + /// + /// 将ushort值以小端序写入字节数组 + /// + public static void TryWriteBytes(byte[] buffer, ushort value, int offset = 0) + { + buffer[offset] = (byte)value; // 低位字节 + buffer[offset + 1] = (byte)(value >> 8); // 高位字节 + } + + /// + /// 将uint值以小端序写入字节数组 + /// + 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 (最高位) + } + + /// + /// 将int值以小端序写入字节数组 + /// + 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 span) + { + return System.BitConverter.ToUInt16(span.ToArray(), 0); + } + } +#endif /// /// 心跳包数据 /// @@ -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 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 srcdata, out UInt16 CmdID, out byte[] data) @@ -71,4 +223,4 @@ namespace HaoYueNet.ClientNetwork } } } -} +} \ No newline at end of file diff --git a/NetLib/HaoYueNet.ClientNetwork/IOCPMode/TcpSaeaClient.cs b/NetLib/HaoYueNet.ClientNetwork/IOCPMode/TcpSaeaClient.cs index d24940e..d04fa3c 100644 --- a/NetLib/HaoYueNet.ClientNetwork/IOCPMode/TcpSaeaClient.cs +++ b/NetLib/HaoYueNet.ClientNetwork/IOCPMode/TcpSaeaClient.cs @@ -380,14 +380,14 @@ namespace HaoYueNet.ClientNetwork.IOCPMode long FristBeginPos = token.memoryStream.Position; //从Byte池申请 - byte[] lenBytes = ArrayPool.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.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.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.Shared.Return(rev_fromArrayPool); + BytesArrayPool.ReturnBuffer(rev_fromArrayPool); } while (token.memoryStream.Length > 4); } diff --git a/NetLib/HaoYueNet.ClientNetwork/NetworkHelperCore.cs b/NetLib/HaoYueNet.ClientNetwork/NetworkHelperCore.cs index 1461a88..9190dc9 100644 --- a/NetLib/HaoYueNet.ClientNetwork/NetworkHelperCore.cs +++ b/NetLib/HaoYueNet.ClientNetwork/NetworkHelperCore.cs @@ -22,9 +22,9 @@ namespace HaoYueNet.ClientNetwork private static int MaxSendIndexNum = 3; //响应倒计时计数 - private static int RevIndex=0; + private static int RevIndex = 0; //发送倒计时计数 - private static int SendIndex=0; + private static int SendIndex = 0; //计时器间隔 private static int TimerInterval = 3000; @@ -35,7 +35,7 @@ namespace HaoYueNet.ClientNetwork public static int LastConnectPort; public bool bDetailedLog = false; - public bool Init(string IP, int port,bool isHadDetailedLog = true, bool bBindReuseAddress = false,int bBindport = 0,AddressFamily addressFamily = AddressFamily.InterNetwork) + public bool Init(string IP, int port, bool isHadDetailedLog = true, bool bBindReuseAddress = false, int bBindport = 0, AddressFamily addressFamily = AddressFamily.InterNetwork) { LogOut("==>初始化网络核心"); @@ -60,7 +60,7 @@ namespace HaoYueNet.ClientNetwork //带回调的 try { - if(bDetailedLog) + if (bDetailedLog) LogOut("连接到远程IP " + IP + ":" + port); else LogOut("连接到远程服务"); @@ -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 /// 发送数据并计数 /// /// - private void SendWithIndex(byte[] data) + private void SendWithIndex(byte[] data, int usefulLenght) { - lock (sendLock) + lock (sendLock) { //增加发送计数 SendIndex = MaxSendIndexNum; //发送数据 - client.Send(data); + client.Send(data, usefulLenght, SocketFlags.None); } } @@ -161,10 +161,32 @@ namespace HaoYueNet.ClientNetwork /// /// /// 序列化之后的数据 - 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); + } + + /// + /// 供外部调用 发送消息 + /// + /// + /// 序列化之后的数据 + 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 事件定义 @@ -205,7 +227,7 @@ namespace HaoYueNet.ClientNetwork { OnCloseReady(); } - + private void DataCallBackReady(byte[] data) { @@ -244,7 +266,7 @@ namespace HaoYueNet.ClientNetwork return; } } - catch(Exception ex) + catch (Exception ex) { //清理数据 reciveMemoryStream.SetLength(0); diff --git a/NetLib/HaoYueNet.ClientNetwork/NetworkHelperP2PCore.cs b/NetLib/HaoYueNet.ClientNetwork/NetworkHelperP2PCore.cs index de60879..4e5fbe0 100644 --- a/NetLib/HaoYueNet.ClientNetwork/NetworkHelperP2PCore.cs +++ b/NetLib/HaoYueNet.ClientNetwork/NetworkHelperP2PCore.cs @@ -15,22 +15,22 @@ namespace HaoYueNet.ClientNetwork private static int MaxSendIndexNum = 3; //响应倒计时计数 - private static int RevIndex=0; + private static int RevIndex = 0; //发送倒计时计数 - private static int SendIndex=0; + private static int SendIndex = 0; //计时器间隔 private static int TimerInterval = 3000; private System.Timers.Timer _heartTimer; - public void Init(bool bBindReuseAddress = false,int bBindport = 0, AddressFamily addressFamily = AddressFamily.InterNetwork) + public void Init(bool bBindReuseAddress = false, int bBindport = 0, AddressFamily addressFamily = AddressFamily.InterNetwork) { LogOut("==>初始化网络核心"); RevIndex = MaxRevIndexNum; SendIndex = MaxSendIndexNum; - client = new Socket(addressFamily,SocketType.Stream, ProtocolType.Tcp); + client = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp); if (bBindReuseAddress) { client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); @@ -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 /// 发送数据并计数 /// /// - private void SendWithIndex(byte[] data) + private void SendWithIndex(byte[] data, int usefulLenght) { //增加发送计数 SendIndex = MaxSendIndexNum; //发送数据 - client.Send(data); + client.Send(data, usefulLenght, SocketFlags.None); } /// @@ -130,8 +130,15 @@ namespace HaoYueNet.ClientNetwork /// 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); @@ -175,7 +182,7 @@ namespace HaoYueNet.ClientNetwork { OnCloseReady(); } - + private void DataCallBackReady(byte[] data) { diff --git a/NetLib/HaoYueNet.ClientNetwork/OtherMode/NetworkHelperCore_ListenerMode.cs b/NetLib/HaoYueNet.ClientNetwork/OtherMode/NetworkHelperCore_ListenerMode.cs index 75c86bc..767a705 100644 --- a/NetLib/HaoYueNet.ClientNetwork/OtherMode/NetworkHelperCore_ListenerMode.cs +++ b/NetLib/HaoYueNet.ClientNetwork/OtherMode/NetworkHelperCore_ListenerMode.cs @@ -199,7 +199,7 @@ namespace HaoYueNet.ClientNetwork.OtherMode while (true) { //申请byte池 一定要记得回收!! - byte[] rev_fromArrayPool = ArrayPool.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.Shared.Return(rev_fromArrayPool); + BytesArrayPool.ReturnBuffer(rev_fromArrayPool); return; } } @@ -232,7 +232,7 @@ namespace HaoYueNet.ClientNetwork.OtherMode reciveMemoryStream.Write(rev_fromArrayPool, 0, effective);//将接受到的数据写入内存流中 //回收 - ArrayPool.Shared.Return(rev_fromArrayPool); + BytesArrayPool.ReturnBuffer(rev_fromArrayPool); DataCallBackReady(client, reciveMemoryStream.ToArray()); //流复用的方式 不用重新new申请 diff --git a/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/BaseData.cs b/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/BaseData.cs index 6cddadf..4424a80 100644 --- a/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/BaseData.cs +++ b/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/BaseData.cs @@ -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.Shared.Rent(minSize); + } + + public static void ReturnBuffer(byte[] buffer) + { + ArrayPool.Shared.Return(buffer); + } + } public static class BaseData { + +#if NETSTANDARD2_0_OR_GREATER + static class BitConverter + { + /// + /// 将short值以小端序写入字节数组 + /// + /// 目标字节数组 + /// 要写入的short值 + /// 写入起始位置 + public static void TryWriteBytes(byte[] buffer, short value, int offset = 0) + { + // 小端序:低位在前,高位在后 + buffer[offset] = (byte)value; // 低位字节 + buffer[offset + 1] = (byte)(value >> 8); // 高位字节 + } + + /// + /// 将ushort值以小端序写入字节数组 + /// + public static void TryWriteBytes(byte[] buffer, ushort value, int offset = 0) + { + buffer[offset] = (byte)value; // 低位字节 + buffer[offset + 1] = (byte)(value >> 8); // 高位字节 + } + + /// + /// 将uint值以小端序写入字节数组 + /// + 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 (最高位) + } + + /// + /// 将int值以小端序写入字节数组 + /// + 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 span) + { + return System.BitConverter.ToUInt16(span.ToArray(), 0); + } + } +#endif /// /// 心跳包数据 /// @@ -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 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 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(); } } diff --git a/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/IOCPMode/TcpSaeaClient.cs b/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/IOCPMode/TcpSaeaClient.cs index e76d39b..81b37e5 100644 --- a/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/IOCPMode/TcpSaeaClient.cs +++ b/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/IOCPMode/TcpSaeaClient.cs @@ -383,14 +383,14 @@ namespace HaoYueNet.ClientNetwork.IOCPMode long FristBeginPos = token.memoryStream.Position; //从Byte池申请 - byte[] lenBytes = ArrayPool.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.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.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.Shared.Return(rev_fromArrayPool); + BytesArrayPool.ReturnBuffer(rev_fromArrayPool); } while (token.memoryStream.Length > 4); } diff --git a/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/NetworkHelperCore.cs b/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/NetworkHelperCore.cs index c057ac8..b48a050 100644 --- a/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/NetworkHelperCore.cs +++ b/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/NetworkHelperCore.cs @@ -25,9 +25,9 @@ namespace HaoYueNet.ClientNetwork private static int MaxSendIndexNum = 3; //响应倒计时计数 - private static int RevIndex=0; + private static int RevIndex = 0; //发送倒计时计数 - private static int SendIndex=0; + private static int SendIndex = 0; //计时器间隔 private static int TimerInterval = 3000; @@ -38,7 +38,7 @@ namespace HaoYueNet.ClientNetwork public static int LastConnectPort; public bool bDetailedLog = false; - public bool Init(string IP, int port,bool isHadDetailedLog = true, bool bBindReuseAddress = false,int bBindport = 0,AddressFamily addressFamily = AddressFamily.InterNetwork) + public bool Init(string IP, int port, bool isHadDetailedLog = true, bool bBindReuseAddress = false, int bBindport = 0, AddressFamily addressFamily = AddressFamily.InterNetwork) { LogOut("==>初始化网络核心"); @@ -63,7 +63,7 @@ namespace HaoYueNet.ClientNetwork //带回调的 try { - if(bDetailedLog) + if (bDetailedLog) LogOut("连接到远程IP " + IP + ":" + port); else LogOut("连接到远程服务"); @@ -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 /// 发送数据并计数 /// /// - private void SendWithIndex(byte[] data) + private void SendWithIndex(byte[] data, int usefulLenght) { - lock (sendLock) + lock (sendLock) { //增加发送计数 SendIndex = MaxSendIndexNum; //发送数据 - client.Send(data); + client.Send(data, usefulLenght, SocketFlags.None); } } @@ -164,12 +164,33 @@ namespace HaoYueNet.ClientNetwork /// /// /// 序列化之后的数据 - 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); } + /// + /// 供外部调用 发送消息 + /// + /// + /// 序列化之后的数据 + 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); @@ -208,7 +229,7 @@ namespace HaoYueNet.ClientNetwork { OnCloseReady(); } - + private void DataCallBackReady(byte[] data) { @@ -247,7 +268,7 @@ namespace HaoYueNet.ClientNetwork return; } } - catch(Exception ex) + catch (Exception ex) { //清理数据 reciveMemoryStream.SetLength(0); diff --git a/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/NetworkHelperP2PCore.cs b/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/NetworkHelperP2PCore.cs index b3e2b52..e5f8c09 100644 --- a/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/NetworkHelperP2PCore.cs +++ b/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/NetworkHelperP2PCore.cs @@ -18,22 +18,22 @@ namespace HaoYueNet.ClientNetwork private static int MaxSendIndexNum = 3; //响应倒计时计数 - private static int RevIndex=0; + private static int RevIndex = 0; //发送倒计时计数 - private static int SendIndex=0; + private static int SendIndex = 0; //计时器间隔 private static int TimerInterval = 3000; private System.Timers.Timer _heartTimer; - public void Init(bool bBindReuseAddress = false,int bBindport = 0, AddressFamily addressFamily = AddressFamily.InterNetwork) + public void Init(bool bBindReuseAddress = false, int bBindport = 0, AddressFamily addressFamily = AddressFamily.InterNetwork) { LogOut("==>初始化网络核心"); RevIndex = MaxRevIndexNum; SendIndex = MaxSendIndexNum; - client = new Socket(addressFamily,SocketType.Stream, ProtocolType.Tcp); + client = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp); if (bBindReuseAddress) { client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); @@ -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 /// 发送数据并计数 /// /// - private void SendWithIndex(byte[] data) + private void SendWithIndex(byte[] data, int usefulLenght) { //增加发送计数 SendIndex = MaxSendIndexNum; //发送数据 - client.Send(data); + client.Send(data, usefulLenght, SocketFlags.None); } /// @@ -133,8 +133,15 @@ namespace HaoYueNet.ClientNetwork /// 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); @@ -178,7 +185,7 @@ namespace HaoYueNet.ClientNetwork { OnCloseReady(); } - + private void DataCallBackReady(byte[] data) { diff --git a/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/OtherMode/NetworkHelperCore_ListenerMode.cs b/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/OtherMode/NetworkHelperCore_ListenerMode.cs index 0e5ee1f..f3be094 100644 --- a/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/OtherMode/NetworkHelperCore_ListenerMode.cs +++ b/NetLib_Standard2/HaoYueNet.ClientNetworkNet.Standard2/OtherMode/NetworkHelperCore_ListenerMode.cs @@ -205,7 +205,7 @@ namespace HaoYueNet.ClientNetwork.OtherMode while (true) { //申请byte池 一定要记得回收!! - byte[] rev_fromArrayPool = ArrayPool.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.Shared.Return(rev_fromArrayPool); + BytesArrayPool.ReturnBuffer(rev_fromArrayPool); return; } } @@ -238,7 +238,7 @@ namespace HaoYueNet.ClientNetwork.OtherMode reciveMemoryStream.Write(rev_fromArrayPool, 0, effective);//将接受到的数据写入内存流中 //回收 - ArrayPool.Shared.Return(rev_fromArrayPool); + BytesArrayPool.ReturnBuffer(rev_fromArrayPool); DataCallBackReady(client, reciveMemoryStream.ToArray()); //流复用的方式 不用重新new申请