From 5ab3985f78f6f1c48ba2090da678b4b8f091469d Mon Sep 17 00:00:00 2001
From: sin365 <353374337@qq.com>
Date: Mon, 15 Jan 2024 11:28:29 +0800
Subject: [PATCH] =?UTF-8?q?=E7=B2=BE=E7=AE=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../NetworkHelperCore.cs | 19 -
NetLib/HaoYueNet.ServerNetwork/BaseData.cs | 1 -
.../NetWork/TcpSaeaServer.cs | 364 +++++++-----------
3 files changed, 135 insertions(+), 249 deletions(-)
diff --git a/NetLib/HaoYueNet.ClientNetwork/NetworkHelperCore.cs b/NetLib/HaoYueNet.ClientNetwork/NetworkHelperCore.cs
index bc0c88e..a92d0ed 100644
--- a/NetLib/HaoYueNet.ClientNetwork/NetworkHelperCore.cs
+++ b/NetLib/HaoYueNet.ClientNetwork/NetworkHelperCore.cs
@@ -206,24 +206,6 @@ namespace HaoYueNet.ClientNetwork
///
public event OnLogOutHandler OnLogOut;
- /////
- ///// 用于调用者回调的虚函数
- /////
- /////
- //public virtual void DataCallBack(int CMDID,int ERRCODE,byte[] data)
- //{
-
- //}
-
- /////
- ///// 断开连接
- /////
- /////
- //public virtual void OnClose()
- //{
-
- //}
-
///
/// 做好处理的连接管理
///
@@ -240,7 +222,6 @@ namespace HaoYueNet.ClientNetwork
OnClose?.Invoke();
}
-
///
/// 主动关闭连接
///
diff --git a/NetLib/HaoYueNet.ServerNetwork/BaseData.cs b/NetLib/HaoYueNet.ServerNetwork/BaseData.cs
index 643e534..6ba2913 100644
--- a/NetLib/HaoYueNet.ServerNetwork/BaseData.cs
+++ b/NetLib/HaoYueNet.ServerNetwork/BaseData.cs
@@ -1,5 +1,4 @@
using System.Net.Sockets;
-using static System.Runtime.InteropServices.JavaScript.JSType;
namespace HaoYueNet.ServerNetwork
{
diff --git a/NetLib/HaoYueNet.ServerNetwork/NetWork/TcpSaeaServer.cs b/NetLib/HaoYueNet.ServerNetwork/NetWork/TcpSaeaServer.cs
index 2c100d2..bd3b354 100644
--- a/NetLib/HaoYueNet.ServerNetwork/NetWork/TcpSaeaServer.cs
+++ b/NetLib/HaoYueNet.ServerNetwork/NetWork/TcpSaeaServer.cs
@@ -7,21 +7,11 @@ namespace HaoYueNet.ServerNetwork
{
public class TcpSaeaServer
{
- //响应倒计时计数最大值
- //public int MaxRevIndexNum { get; set; } = 5;
- ////发送倒计时计数最大值
- //public int MaxSendIndexNum { get; set; } = 3;
-
- //响应倒计时计数最大值
- public int MaxRevIndexNum { get; set; } = 50;
- //发送倒计时计数最大值
- public int MaxSendIndexNum { get; set; } = 3;
- //计时器间隔
- private static int TimerInterval = 3000;
- ///
- /// 心跳包计数器
- ///
- private System.Timers.Timer _heartTimer;
+ #region 定义属性
+ protected int MaxRevIndexNum = 50;//响应倒计时计数最大值
+ protected int MaxSendIndexNum = 3;//发送倒计时计数最大值
+ protected static int TimerInterval = 3000;//计时器间隔
+ protected System.Timers.Timer _heartTimer;//心跳包计数器
public int m_maxConnectNum; //最大连接数
public int m_revBufferSize; //最大接收字节数
protected BufferManager m_bufferManager;
@@ -32,10 +22,10 @@ namespace HaoYueNet.ServerNetwork
protected TokenMsgPool msg_pool;
protected int m_clientCount; //连接的客户端数量
protected Semaphore m_maxNumberAcceptedClients;//信号量
- List m_clients; //客户端列表
-
protected Dictionary _DictSocketAsyncUserToken = new Dictionary();
-
+ List m_clients; //客户端列表
+ public List ClientList { private set { m_clients = value; } get { return m_clients; } } //获取客户端列表
+ #endregion
#region 定义委托
///
@@ -81,16 +71,9 @@ namespace HaoYueNet.ServerNetwork
public event OnNetLogHandler OnNetLog;
#endregion
- #region 定义属性
- ///
- /// 获取客户端列表
- ///
- public List ClientList { get { return m_clients; } }
- #endregion
-
- ///
- /// 构造函数
- ///
+ ///
+ /// 构造函数
+ ///
/// 最大连接数
/// 缓存区大小
public TcpSaeaServer(int numConnections, int receiveBufferSize)
@@ -110,7 +93,7 @@ namespace HaoYueNet.ServerNetwork
m_maxNumberAcceptedClients = new Semaphore(numConnections, numConnections);
}
- #region 连接操作
+ #region Client操作
///
/// 初始化
///
@@ -147,7 +130,6 @@ namespace HaoYueNet.ServerNetwork
}
OutNetLog("初始化完毕");
}
-
///
/// 启动服务
///
@@ -188,7 +170,6 @@ namespace HaoYueNet.ServerNetwork
return false;
}
}
-
///
/// 停止服务
///
@@ -215,38 +196,42 @@ namespace HaoYueNet.ServerNetwork
if (OnClientNumberChange != null)
OnClientNumberChange(-c_count, null);
}
-
public void CloseClient(AsyncUserToken token)
{
- try
- {
- token.Socket.Shutdown(SocketShutdown.Both);
- }
+ try {token.Socket.Shutdown(SocketShutdown.Both);}
catch (Exception) { }
}
-
- //关闭客户端连接
- private void CloseClientSocket(SocketAsyncEventArgs e)
+ ///
+ /// 关闭客户端连接
+ ///
+ ///
+ void CloseClientSocket(SocketAsyncEventArgs e)
{
AsyncUserToken token = e.UserToken as AsyncUserToken;
- //调用关闭连接
+ CloseReady(token);
+ // 释放SocketAsyncEventArg,以便其他客户端可以重用它们
+ ReleaseSocketAsyncEventArgs(e);
+ }
+ void CloseReady(AsyncUserToken token)
+ {
OnDisconnected?.Invoke(token);
RemoveUserToken(token);
- //如果有事件,则调用事件,发送客户端数量变化通知
+ //如果有事件,则调用事件,发送客户端数量变化通知
OnClientNumberChange?.Invoke(-1, token);
- // close the socket associated with the client
- try { token.Socket.Shutdown(SocketShutdown.Send); }
- catch (Exception) { }
+ // 关闭与客户端关联的套接字
+ try { token.Socket.Shutdown(SocketShutdown.Send); } catch (Exception) { }
token.Socket.Close();
- // decrement the counter keeping track of the total number of clients connected to the server
+ // 递减计数器以跟踪连接到服务器的客户端总数
Interlocked.Decrement(ref m_clientCount);
m_maxNumberAcceptedClients.Release();
- // Free the SocketAsyncEventArg so they can be reused by another client
- ReleaseSocketAsyncEventArgs(e);
}
#endregion
#region Token管理
+ public AsyncUserToken GetAsyncUserTokenForSocket(Socket sk)
+ {
+ return _DictSocketAsyncUserToken.ContainsKey(sk) ? _DictSocketAsyncUserToken[sk] : null;
+ }
void AddUserToken(AsyncUserToken userToken)
{
lock (_DictSocketAsyncUserToken)
@@ -271,17 +256,38 @@ namespace HaoYueNet.ServerNetwork
_DictSocketAsyncUserToken.Clear();
}
}
- public AsyncUserToken GetAsyncUserTokenForSocket(Socket sk)
+ ///
+ /// 回收SocketAsyncEventArgs
+ ///
+ ///
+ ///
+ void ReleaseSocketAsyncEventArgs(SocketAsyncEventArgs saea)
{
- return _DictSocketAsyncUserToken.ContainsKey(sk) ? _DictSocketAsyncUserToken[sk] : null;
+ //saea.UserToken = null;//TODO
+ //saea.SetBuffer(null, 0, 0);
+ //saea.Dispose();
+ //↑ 这里不要自作主张去清东西,否则回收回去不可用
+
+ switch (saea.LastOperation)
+ {
+ case SocketAsyncOperation.Receive:
+ m_Receivepool.Push(saea);
+ break;
+ case SocketAsyncOperation.Send:
+ m_Sendpool.Push(saea);
+ break;
+ default:
+ throw new ArgumentException("ReleaseSocketAsyncEventArgs > The last operation completed on the socket was not a receive or send");
+ }
+
}
#endregion
- #region 监听客户端建立连接
- // Begins an operation to accept a connection request from the client
- //
- // The context object to use when issuing
- // the accept operation on the server's listening socket
+ #region 监听IOCP循环
+ ///
+ /// 开始接受客户端的连接请求的操作
+ ///
+ /// 在服务器的侦听套接字上发出接受操作时要使用的上下文对象
public void StartAccept(SocketAsyncEventArgs acceptEventArg)
{
if (acceptEventArg == null)
@@ -301,15 +307,15 @@ namespace HaoYueNet.ServerNetwork
ProcessAccept(acceptEventArg);
}
}
-
- // This method is the callback method associated with Socket.AcceptAsync
- // operations and is invoked when an accept operation is complete
- //
+ ///
+ /// 此方法是与Socket关联的回调方法。AcceptAsync操作,并在接受操作完成时调用
+ ///
+ ///
+ ///
void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
{
ProcessAccept(e);
}
-
private void ProcessAccept(SocketAsyncEventArgs e)
{
try
@@ -352,11 +358,12 @@ namespace HaoYueNet.ServerNetwork
}
#endregion
- #region 完成端口收发处理
- // This method is invoked when an asynchronous receive operation completes.
- // If the remote host closed the connection, then the socket is closed.
- // If data was received then the data is echoed back to the client.
- //
+ #region 收发IOCP循环
+ /// 当异步接收操作完成时,会调用此方法。
+ /// 如果远程主机关闭了连接,则套接字关闭。
+ /// 如果接收到数据,则将数据回显到客户端。
+ ///
+ ///
private void ProcessReceive(SocketAsyncEventArgs e)
{
try
@@ -474,37 +481,30 @@ namespace HaoYueNet.ServerNetwork
default:
throw new ArgumentException("The last operation completed on the socket was not a receive or send");
}
-
}
#endregion
- ///
- /// 回收SocketAsyncEventArgs
- ///
- ///
- void ReleaseSocketAsyncEventArgs(SocketAsyncEventArgs saea)
- {
- //saea.UserToken = null;//TODO
- //saea.SetBuffer(null, 0, 0);
- //saea.Dispose();
- //↑ 这里不要自作主张去清东西,否则回收回去不可用
-
- switch (saea.LastOperation)
- {
- case SocketAsyncOperation.Receive:
- m_Receivepool.Push(saea);
- break;
- case SocketAsyncOperation.Send:
- m_Sendpool.Push(saea);
- break;
- default:
- throw new ArgumentException("ReleaseSocketAsyncEventArgs > The last operation completed on the socket was not a receive or send");
- }
-
- }
-
+ #region 发送
int sendrun = 0;
- private void SendForMsgPool()
+ ///
+ /// 对外暴露的发送消息
+ ///
+ ///
+ /// 序列化之后的数据
+ public void SendToSocket(Socket sk, int CMDID, int ERRCODE, byte[] data)
+ {
+ AsyncUserToken token = GetAsyncUserTokenForSocket(sk);
+ /*HunterNet_S2C _s2cdata = new HunterNet_S2C();
+ _s2cdata.HunterNetCoreCmdID = CMDID;
+ _s2cdata.HunterNetCoreData = ByteString.CopyFrom(data);
+ _s2cdata.HunterNetCoreERRORCode = ERRCODE;
+ byte[] _finaldata = Serizlize(_s2cdata);*/
+
+ //byte[] _finaldata = HunterNet_S2C.CreatePkgData((ushort)CMDID, (ushort)ERRCODE, data);
+
+ SendWithIndex(token, (ushort)CMDID, (ushort)ERRCODE, data);
+ }
+ void SendForMsgPool()
{
//if (flag_SendForMsgPool) return;
try
@@ -526,7 +526,7 @@ namespace HaoYueNet.ServerNetwork
}
else
{
- SendMessage(msg.token,msg.CMDID,msg.Error,msg.data);
+ SendMessage(msg.token, msg.CMDID, msg.Error, msg.data);
}
msg = null;
}
@@ -544,84 +544,12 @@ namespace HaoYueNet.ServerNetwork
}
}
- /*
- public void SendMessage(AsyncUserToken token, byte[] message,bool dontNeedHead = false)
- {
- if (token == null || token.Socket == null || !token.Socket.Connected)
- return;
- try
- {
- if (!dontNeedHead)
- {
- message = SendDataWithHead(message);
- }
- if (m_Sendpool.Count > 0)
- {
- SocketAsyncEventArgs myreadEventArgs = m_Sendpool.Pop();
- myreadEventArgs.UserToken = token;
- myreadEventArgs.AcceptSocket = token.Socket;
- myreadEventArgs.SetBuffer(message, 0, message.Length); //将数据放置进去.
-
- //若不需要等待
- if (!token.Socket.SendAsync(myreadEventArgs))
- {
- m_Sendpool.Push(myreadEventArgs);
- }
- return;
- }
- else
- {
- //先压入队列,等待m_Sendpool回收
- msg_pool.Enqueue(new TokenWithMsg() { token = token, message = message });
- //OutNetLog("!!!!压入消息发送队列MSG_Pool");
- return;
- }
- }
- catch (Exception e)
- {
- OutNetLog(e.ToString());
- }
- }
- */
-
- public void SendMessage(AsyncUserToken token,UInt16 CmdID, UInt16 Error, byte[] data)
- {
- if (token == null || token.Socket == null || !token.Socket.Connected)
- return;
- try
- {
- if (m_Sendpool.Count > 0)
- {
- SocketAsyncEventArgs myreadEventArgs = m_Sendpool.Pop();
- myreadEventArgs.UserToken = token;
- myreadEventArgs.AcceptSocket = token.Socket;
- //myreadEventArgs.SetBuffer(message, 0, message.Length); //将数据放置进去.
- //更换为CMDID和Data直接写入SocketAsyncEventArgs的Buff
- HunterNet_S2C.SetDataToSocketAsyncEventArgs(myreadEventArgs, CmdID, Error, data);
-
- //若不需要等待
- if (!token.Socket.SendAsync(myreadEventArgs))
- {
- m_Sendpool.Push(myreadEventArgs);
- }
- return;
- }
- else
- {
- //先压入队列,等待m_Sendpool回收
- msg_pool.Enqueue(new TokenWithMsg() { token = token, CMDID = CmdID, Error = Error, data = data });
- //OutNetLog("!!!!压入消息发送队列MSG_Pool");
- return;
- }
- }
- catch (Exception e)
- {
- OutNetLog(e.ToString());
- }
- }
-
- public void SendHeartbeatMessage(AsyncUserToken token)
+ ///
+ /// 发送心跳包
+ ///
+ ///
+ void SendHeartbeatMessage(AsyncUserToken token)
{
if (token == null || token.Socket == null || !token.Socket.Connected)
return;
@@ -656,49 +584,11 @@ namespace HaoYueNet.ServerNetwork
}
}
- //拼接头部长度
- private static byte[] SendDataWithHead(byte[] message)
- {
-
- MemoryStream memoryStream = new MemoryStream();//创建一个内存流
-
- byte[] BagHead = BitConverter.GetBytes(message.Length + 4);//往字节数组中写入包头(包头自身的长度和消息体的长度)的长度
-
- memoryStream.Write(BagHead, 0, BagHead.Length);//将包头写入内存流
- memoryStream.Write(message, 0, message.Length);//将消息体写入内存流
-
- byte[] HeadAndBody = memoryStream.ToArray();//将内存流中的数据写入字节数组
-
- memoryStream.Close();//关闭内存
- memoryStream.Dispose();//释放资源
-
- return HeadAndBody;
- }
-
- #region
- private void OnCloseReady(AsyncUserToken token)
- {
- OnDisconnected?.Invoke(token);
- RemoveUserToken(token);
- //如果有事件,则调用事件,发送客户端数量变化通知
- OnClientNumberChange?.Invoke(-1, token);
- // close the socket associated with the client
- try
- {
- token.Socket.Shutdown(SocketShutdown.Send);
- }
- catch (Exception) { }
- token.Socket.Close();
- // decrement the counter keeping track of the total number of clients connected to the server
- Interlocked.Decrement(ref m_clientCount);
- m_maxNumberAcceptedClients.Release();
- }
-
///
/// 发送数据并计数
///
///
- private void SendWithIndex(AsyncUserToken token, UInt16 CmdID, UInt16 ERRCODE, byte[] data)
+ void SendWithIndex(AsyncUserToken token, UInt16 CmdID, UInt16 ERRCODE, byte[] data)
{
try
{
@@ -708,29 +598,48 @@ namespace HaoYueNet.ServerNetwork
}
catch
{
- OnCloseReady(token);
+ CloseReady(token);
}
}
- ///
- /// 对外暴露的发送消息
- ///
- ///
- /// 序列化之后的数据
- public void SendToSocket(Socket sk, int CMDID, int ERRCODE, byte[] data)
+ void SendMessage(AsyncUserToken token, UInt16 CmdID, UInt16 Error, byte[] data)
{
- AsyncUserToken token = GetAsyncUserTokenForSocket(sk);
- /*HunterNet_S2C _s2cdata = new HunterNet_S2C();
- _s2cdata.HunterNetCoreCmdID = CMDID;
- _s2cdata.HunterNetCoreData = ByteString.CopyFrom(data);
- _s2cdata.HunterNetCoreERRORCode = ERRCODE;
- byte[] _finaldata = Serizlize(_s2cdata);*/
+ if (token == null || token.Socket == null || !token.Socket.Connected)
+ return;
+ try
+ {
+ if (m_Sendpool.Count > 0)
+ {
+ SocketAsyncEventArgs myreadEventArgs = m_Sendpool.Pop();
+ myreadEventArgs.UserToken = token;
+ myreadEventArgs.AcceptSocket = token.Socket;
+ //myreadEventArgs.SetBuffer(message, 0, message.Length); //将数据放置进去.
+ //更换为CMDID和Data直接写入SocketAsyncEventArgs的Buff
+ HunterNet_S2C.SetDataToSocketAsyncEventArgs(myreadEventArgs, CmdID, Error, data);
- //byte[] _finaldata = HunterNet_S2C.CreatePkgData((ushort)CMDID, (ushort)ERRCODE, data);
-
- SendWithIndex(token, (ushort)CMDID, (ushort)ERRCODE, data);
+ //若不需要等待
+ if (!token.Socket.SendAsync(myreadEventArgs))
+ {
+ m_Sendpool.Push(myreadEventArgs);
+ }
+ return;
+ }
+ else
+ {
+ //先压入队列,等待m_Sendpool回收
+ msg_pool.Enqueue(new TokenWithMsg() { token = token, CMDID = CmdID, Error = Error, data = data });
+ //OutNetLog("!!!!压入消息发送队列MSG_Pool");
+ return;
+ }
+ }
+ catch (Exception e)
+ {
+ OutNetLog(e.ToString());
+ }
}
+ #endregion
+ #region 处理前预备
private void DataCallBackReady(AsyncUserToken sk, byte[] data)
{
//增加接收计数
@@ -760,7 +669,6 @@ namespace HaoYueNet.ServerNetwork
}
}
}
-
private void OutNetLog(string msg)
{
OnNetLog?.Invoke(msg);
@@ -768,7 +676,6 @@ namespace HaoYueNet.ServerNetwork
#endregion
#region 心跳包
-
///
/// 发送心跳包
///
@@ -786,7 +693,7 @@ namespace HaoYueNet.ServerNetwork
}
catch (Exception e)
{
- OnCloseReady(token);
+ CloseReady(token);
}
}
///
@@ -803,7 +710,7 @@ namespace HaoYueNet.ServerNetwork
if (m_clients[i].RevIndex <= 0)
{
//判定掉线
- OnCloseReady(m_clients[i]);
+ CloseReady(m_clients[i]);
return;
}
@@ -818,6 +725,5 @@ namespace HaoYueNet.ServerNetwork
}
}
#endregion
-
}
}