From f2e0279fd9144bf43f1c82d3e50b6784baac889c Mon Sep 17 00:00:00 2001
From: sin365 <353374337@qq.com>
Date: Fri, 29 Mar 2024 17:49:19 +0800
Subject: [PATCH] =?UTF-8?q?=E6=9A=82=E6=97=B6=E4=B8=8D=E4=BD=BF=E7=94=A8Me?=
=?UTF-8?q?moryStream=EF=BC=8C=E4=BC=98=E5=8C=96=E5=90=8E=E9=87=8D?=
=?UTF-8?q?=E6=96=B0=E4=BD=BF=E7=94=A8=EF=BC=8C=E4=BB=A5=E5=8F=8A=E5=AE=A2?=
=?UTF-8?q?=E6=88=B7=E7=AB=AF=E5=BA=93=E7=9A=84=E5=8E=9F=E7=94=9FListener?=
=?UTF-8?q?=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../NetworkHelperCore.cs | 12 +-
.../NetworkHelperCore_ListenerMode.cs | 165 +++++++++++-------
.../NetWork/AsyncUserToken.cs | 8 +-
.../SourceMode/TcpSaeaServer_SourceMode.cs | 41 +++--
.../NetWork/TcpSaeaServer.cs | 116 ++++++------
5 files changed, 200 insertions(+), 142 deletions(-)
diff --git a/NetLib/HaoYueNet.ClientNetwork/NetworkHelperCore.cs b/NetLib/HaoYueNet.ClientNetwork/NetworkHelperCore.cs
index a92d0ed..977e689 100644
--- a/NetLib/HaoYueNet.ClientNetwork/NetworkHelperCore.cs
+++ b/NetLib/HaoYueNet.ClientNetwork/NetworkHelperCore.cs
@@ -141,16 +141,20 @@ namespace HaoYueNet.ClientNetwork
//LogOut("发送心跳包");
}
+ object sendLock = new object();
///
/// 发送数据并计数
///
///
private void SendWithIndex(byte[] data)
{
- //增加发送计数
- SendIndex = MaxSendIndexNum;
- //发送数据
- client.Send(data);
+ lock (sendLock)
+ {
+ //增加发送计数
+ SendIndex = MaxSendIndexNum;
+ //发送数据
+ client.Send(data);
+ }
}
////拼接头长度
diff --git a/NetLib/HaoYueNet.ClientNetwork/OtherMode/NetworkHelperCore_ListenerMode.cs b/NetLib/HaoYueNet.ClientNetwork/OtherMode/NetworkHelperCore_ListenerMode.cs
index d09d385..be178e1 100644
--- a/NetLib/HaoYueNet.ClientNetwork/OtherMode/NetworkHelperCore_ListenerMode.cs
+++ b/NetLib/HaoYueNet.ClientNetwork/OtherMode/NetworkHelperCore_ListenerMode.cs
@@ -7,7 +7,7 @@ namespace HaoYueNet.ClientNetwork.OtherMode
public class NetworkHelperCore_ListenerMode
{
private Socket serversocket;
- private Socket client;
+ private Dictionary mDictHandleClient;
//响应倒计时计数最大值
private static int MaxRevIndexNum = 50;
@@ -28,65 +28,109 @@ namespace HaoYueNet.ClientNetwork.OtherMode
public void Init(int port)
{
+ mDictHandleClient = new Dictionary();
+
LogOut("==>初始化NetworkHelperCore_ListenerMode");
serversocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, port);
serversocket.Bind(endPoint); // 绑定
serversocket.Listen(1);
- client = serversocket.Accept(); // 接收客户端连接
- OnConnected?.Invoke(true);
- Console.WriteLine("客户端连接成功 信息: " + client.AddressFamily.ToString());
- Thread revThread = new Thread(Recive);
- revThread.Start(client);
+ //client = serversocket.Accept(); // 接收客户端连接
+ //OnConnected?.Invoke(true);
+ //Console.WriteLine("客户端连接成功 信息: " + client.AddressFamily.ToString());
+ //Thread revThread = new Thread(Recive);
+ //revThread.Start(client);
+
+ Task task = new Task(() =>
+ {
+ while (true)
+ {
+ Socket newclient;
+ try
+ {
+ newclient = serversocket.Accept(); // 接收客户端连接
+ }
+ catch
+ {
+ break;
+ }
+ AddDictSocket(newclient);
+ OnConnected?.Invoke(newclient);
+ Console.WriteLine("客户端连接成功 信息: " + newclient.AddressFamily.ToString());
+ Thread revThread = new Thread(Recive);
+ revThread.Start(newclient);
+ }
+ });
+ task.Start();
}
+ #region
+
+ ///
+ /// 追加Socket返回下标
+ ///
+ ///
+ ///
+ public void AddDictSocket(Socket socket)
+ {
+ if (socket == null)
+ return;
+ lock (mDictHandleClient)
+ {
+ mDictHandleClient[socket.Handle] = socket;
+ }
+ }
+
+ public void RemoveDictSocket(Socket socket)
+ {
+ if (socket == null)
+ return;
+ lock (mDictHandleClient)
+ {
+ if (!mDictHandleClient.ContainsKey(socket.Handle))
+ return;
+ mDictHandleClient.Remove(socket.Handle);
+ }
+ }
+ #endregion
+
~NetworkHelperCore_ListenerMode()
{
- client.Close();
+ nint[] keys = mDictHandleClient.Keys.ToArray();
+ for (uint i = 0; i < keys.Length; i++)
+ {
+ mDictHandleClient[keys[i]].Close();
+ }
+ mDictHandleClient.Clear();
}
- private void SendToSocket(byte[] data)
+ private void SendToSocket(Socket socket, byte[] data)
{
//已拼接包长度,这里不再需要拼接长度
//data = SendDataWithHead(data);
try
{
- SendWithIndex(data);
+ SendWithIndex(socket,data);
}
catch (Exception ex)
{
//连接断开
- OnCloseReady();
+ OnCloseReady(socket);
return;
}
//LogOut("发送消息,消息长度=> "+data.Length);
}
- private void SendHeartbeat()
- {
- try
- {
- SendWithIndex(HeartbeatData);
- }
- catch (Exception ex)
- {
- //连接断开
- OnCloseReady();
- return;
- }
- //LogOut("发送心跳包");
- }
-
///
/// 发送数据并计数
///
///
- private void SendWithIndex(byte[] data)
+ private void SendWithIndex(Socket socket,byte[] data)
{
//增加发送计数
SendIndex = MaxSendIndexNum;
//发送数据
- client.Send(data);
+ socket.Send(data);
}
///
@@ -94,56 +138,60 @@ namespace HaoYueNet.ClientNetwork.OtherMode
///
///
/// 序列化之后的数据
- public void SendToClient(byte[] data)
+ public void SendToClient(Socket socket, byte[] data)
{
//LogOut("准备数据 data=> "+data);
- SendToSocket(data);
+ SendToSocket(socket, data);
}
#region 事件定义
- public delegate void OnReceiveDataHandler(byte[] data);
- public delegate void OnConnectedHandler(bool IsConnected);
- public delegate void OnCloseHandler();
- public delegate void OnLogOutHandler(string Msg);
+ public delegate void OnConnectedHandler(Socket socket);
+
+ public delegate void OnReceiveDataHandler(Socket sk, byte[] data);
+
+ public delegate void OnDisconnectHandler(Socket sk);
+
+ public delegate void OnNetLogHandler(string msg);
#endregion
public event OnConnectedHandler OnConnected;
- public event OnReceiveDataHandler OnReceiveData;
- public event OnCloseHandler OnClose;
- ///
- /// 网络库调试日志输出
- ///
- public event OnLogOutHandler OnLogOut;
+
+ public event OnReceiveDataHandler OnReceive;
+
+ public event OnDisconnectHandler OnDisconnected;
+
+ public event OnNetLogHandler OnNetLog;
///
/// 做好处理的连接管理
///
- private void OnCloseReady()
+ private void OnCloseReady(Socket socket)
{
LogOut("关闭连接");
//关闭Socket连接
- client.Close();
- OnClose?.Invoke();
+ socket.Close();
+ RemoveDictSocket(socket);
+ OnDisconnected?.Invoke(socket);
}
///
/// 主动关闭连接
///
- public void CloseConntect()
+ public void CloseConntect(Socket socket)
{
- OnCloseReady();
+ OnCloseReady(socket);
}
- private void DataCallBackReady(byte[] data)
+ private void DataCallBackReady(Socket socket,byte[] data)
{
//增加接收计数
RevIndex = MaxRevIndexNum;
- OnReceiveData(data);
+ OnReceive(socket,data);
}
- MemoryStream memoryStream = new MemoryStream();//开辟一个内存流
private void Recive(object o)
{
+ MemoryStream memoryStream = new MemoryStream();//开辟一个内存流
var client = o as Socket;
//MemoryStream memoryStream = new MemoryStream();//开辟一个内存流
@@ -162,20 +210,17 @@ namespace HaoYueNet.ClientNetwork.OtherMode
catch (Exception ex)
{
//远程主机强迫关闭了一个现有的连接
- OnCloseReady();
+ OnCloseReady(client);
return;
//断开连接
}
- memoryStream.Write(buffer, 0, effective);//将接受到的数据写入内存流中
- while (true)
+ if (effective > 0)//如果接受到的消息不为0(不为空)
{
- if (effective > 0)//如果接受到的消息不为0(不为空)
- {
- DataCallBackReady(memoryStream.ToArray());
- //流复用的方式 不用重新new申请
- memoryStream.Position = 0;
- memoryStream.SetLength(0);
- }
+ memoryStream.Write(buffer, 0, effective);//将接受到的数据写入内存流中
+ DataCallBackReady(client, memoryStream.ToArray());
+ //流复用的方式 不用重新new申请
+ memoryStream.Position = 0;
+ memoryStream.SetLength(0);
}
}
}
@@ -183,12 +228,8 @@ namespace HaoYueNet.ClientNetwork.OtherMode
public void LogOut(string Msg)
{
//Console.WriteLine(Msg);
- OnLogOut?.Invoke(Msg);
+ OnNetLog?.Invoke(Msg);
}
- public Socket GetClientSocket()
- {
- return client;
- }
}
}
diff --git a/NetLib/HaoYueNet.ServerNetwork/NetWork/AsyncUserToken.cs b/NetLib/HaoYueNet.ServerNetwork/NetWork/AsyncUserToken.cs
index 1b6df2c..9215aca 100644
--- a/NetLib/HaoYueNet.ServerNetwork/NetWork/AsyncUserToken.cs
+++ b/NetLib/HaoYueNet.ServerNetwork/NetWork/AsyncUserToken.cs
@@ -33,14 +33,14 @@ namespace HaoYueNet.ServerNetwork
///
/// 数据缓存区
///
- //public List Buffer { get; set; }
+ public List Buffer { get; set; }
- public MemoryStream memoryStream { get; set; }
+ //public MemoryStream memoryStream { get; set; }
public AsyncUserToken()
{
- //this.Buffer = new List();
- this.memoryStream = new MemoryStream();
+ this.Buffer = new List();
+ //this.memoryStream = new MemoryStream();
}
///
/// 响应倒计时计数
diff --git a/NetLib/HaoYueNet.ServerNetwork/NetWork/SourceMode/TcpSaeaServer_SourceMode.cs b/NetLib/HaoYueNet.ServerNetwork/NetWork/SourceMode/TcpSaeaServer_SourceMode.cs
index e87ff81..e760ef7 100644
--- a/NetLib/HaoYueNet.ServerNetwork/NetWork/SourceMode/TcpSaeaServer_SourceMode.cs
+++ b/NetLib/HaoYueNet.ServerNetwork/NetWork/SourceMode/TcpSaeaServer_SourceMode.cs
@@ -378,22 +378,35 @@ namespace HaoYueNet.ServerNetwork
if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
{
//读取数据
- lock(token.memoryStream)
+
+ //读取数据
+ byte[] data = new byte[e.BytesTransferred];
+ Array.Copy(e.Buffer, e.Offset, data, 0, e.BytesTransferred);
+ lock (token.Buffer)
+ //lock(token.memoryStream)
{
- //token.Buffer.AddRange(data);
- token.memoryStream.Write(e.Buffer, e.Offset, e.BytesTransferred);
+ token.Buffer.AddRange(data);
+ //token.memoryStream.Write(e.Buffer, e.Offset, e.BytesTransferred);
+ do
+ {
+
+ DataCallBackReady(token, data);
+ //从数据池中移除这组数据
+ lock (token.Buffer)
+ {
+ token.Buffer.Clear();
+ }
+
+ //DataCallBackReady(token, token.memoryStream.ToArray());
+ ////流复用的方式 不用重新new申请
+ //token.memoryStream.Position = 0;
+ //token.memoryStream.SetLength(0);
+
+ //这里API处理完后,并没有返回结果,当然结果是要返回的,却不是在这里, 这里的代码只管接收.
+ //若要返回结果,可在API处理中调用此类对象的SendMessage方法,统一打包发送.不要被微软的示例给迷惑了.
+ //} while (token.memoryStream.Length > 0);
+ } while (token.Buffer.Count > 4);
}
- do
- {
-
- DataCallBackReady(token,token.memoryStream.ToArray());
- //流复用的方式 不用重新new申请
- token.memoryStream.Position = 0;
- token.memoryStream.SetLength(0);
-
- //这里API处理完后,并没有返回结果,当然结果是要返回的,却不是在这里, 这里的代码只管接收.
- //若要返回结果,可在API处理中调用此类对象的SendMessage方法,统一打包发送.不要被微软的示例给迷惑了.
- } while (token.memoryStream.Length > 0);
//继续接收. 为什么要这么写,请看Socket.ReceiveAsync方法的说明
if (!token.Socket.ReceiveAsync(e))
diff --git a/NetLib/HaoYueNet.ServerNetwork/NetWork/TcpSaeaServer.cs b/NetLib/HaoYueNet.ServerNetwork/NetWork/TcpSaeaServer.cs
index 901cc91..56f473e 100644
--- a/NetLib/HaoYueNet.ServerNetwork/NetWork/TcpSaeaServer.cs
+++ b/NetLib/HaoYueNet.ServerNetwork/NetWork/TcpSaeaServer.cs
@@ -378,68 +378,68 @@ namespace HaoYueNet.ServerNetwork
if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
{
//读取数据
- //byte[] data = new byte[e.BytesTransferred];
- //Array.Copy(e.Buffer, e.Offset, data, 0, e.BytesTransferred);
- //lock (token.Buffer)
- lock(token.memoryStream)
+ byte[] data = new byte[e.BytesTransferred];
+ Array.Copy(e.Buffer, e.Offset, data, 0, e.BytesTransferred);
+ lock (token.Buffer)
+ //lock(token.memoryStream)
{
- //token.Buffer.AddRange(data);
- token.memoryStream.Write(e.Buffer, e.Offset, e.BytesTransferred);
- }
- do
- {
- //如果包头不完整
- //if (token.Buffer.Count < 4)
- if (token.memoryStream.Length < 4)
- break;
-
- //判断包的长度
- //byte[] lenBytes = token.Buffer.GetRange(0, 4).ToArray();
- //int packageLen = BitConverter.ToInt32(lenBytes, 0) - 4;
- //if (packageLen > token.Buffer.Count - 4)
- //{ //长度不够时,退出循环,让程序继续接收
- // break;
- //}
-
- long FristBeginPos = token.memoryStream.Position;
- byte[] lenBytes = new byte[4];
- token.memoryStream.Seek(0, SeekOrigin.Begin);
- token.memoryStream.Read(lenBytes,0,4);
- int packageLen = BitConverter.ToInt32(lenBytes, 0) - 4;
- if (packageLen > token.memoryStream.Length - 4)
- { //长度不够时,退出循环,让程序继续接收
- break;
- }
-
- //包够长时,则提取出来,交给后面的程序去处理
- //byte[] rev = token.Buffer.GetRange(4, packageLen).ToArray();
-
- byte[] rev = new byte[packageLen];
- token.memoryStream.Seek(4, SeekOrigin.Begin);
- token.memoryStream.Read(rev, 0, packageLen);
-
- ////从数据池中移除这组数据
- //lock (token.Buffer)
- //{
- // token.Buffer.RemoveRange(0, packageLen + 4);
- //}
-
- token.memoryStream.Seek(FristBeginPos, SeekOrigin.Begin);
- //从数据池中移除这组数据
- lock (token.memoryStream)
+ token.Buffer.AddRange(data);
+ //token.memoryStream.Write(e.Buffer, e.Offset, e.BytesTransferred);
+ do
{
- int numberOfBytesToRemove = packageLen + 4;
- byte[] buf = token.memoryStream.GetBuffer();
- Buffer.BlockCopy(buf, numberOfBytesToRemove, buf, 0, (int)token.memoryStream.Length - numberOfBytesToRemove);
- token.memoryStream.SetLength(token.memoryStream.Length - numberOfBytesToRemove);
- }
+ //如果包头不完整
+ if (token.Buffer.Count < 4)
+ //if (token.memoryStream.Length < 4)
+ break;
- DataCallBackReady(token, rev);
+ //判断包的长度
+ byte[] lenBytes = token.Buffer.GetRange(0, 4).ToArray();
+ int packageLen = BitConverter.ToInt32(lenBytes, 0) - 4;
+ if (packageLen > token.Buffer.Count - 4)
+ { //长度不够时,退出循环,让程序继续接收
+ break;
+ }
- //这里API处理完后,并没有返回结果,当然结果是要返回的,却不是在这里, 这里的代码只管接收.
- //若要返回结果,可在API处理中调用此类对象的SendMessage方法,统一打包发送.不要被微软的示例给迷惑了.
- //} while (token.Buffer.Count > 4);
- } while (token.memoryStream.Length > 4);
+ //long FristBeginPos = token.memoryStream.Position;
+ //byte[] lenBytes = new byte[4];
+ //token.memoryStream.Seek(0, SeekOrigin.Begin);
+ //token.memoryStream.Read(lenBytes, 0, 4);
+ //int packageLen = BitConverter.ToInt32(lenBytes, 0) - 4;
+ //if (packageLen > token.memoryStream.Length - 4)
+ //{ //长度不够时,退出循环,让程序继续接收
+ // break;
+ //}
+
+ //包够长时,则提取出来,交给后面的程序去处理
+ byte[] rev = token.Buffer.GetRange(4, packageLen).ToArray();
+
+ //byte[] rev = new byte[packageLen];
+ //token.memoryStream.Seek(4, SeekOrigin.Begin);
+ //token.memoryStream.Read(rev, 0, packageLen);
+
+ //从数据池中移除这组数据
+ lock (token.Buffer)
+ {
+ token.Buffer.RemoveRange(0, packageLen + 4);
+ }
+
+ //token.memoryStream.Seek(FristBeginPos, SeekOrigin.Begin);
+ ////从数据池中移除这组数据
+ //lock (token.memoryStream)
+ //{
+ // int numberOfBytesToRemove = packageLen + 4;
+ // byte[] buf = token.memoryStream.GetBuffer();
+ // Buffer.BlockCopy(buf, numberOfBytesToRemove, buf, 0, (int)token.memoryStream.Length - numberOfBytesToRemove);
+ // token.memoryStream.SetLength(token.memoryStream.Length - numberOfBytesToRemove);
+ //}
+
+ DataCallBackReady(token, rev);
+
+ //这里API处理完后,并没有返回结果,当然结果是要返回的,却不是在这里, 这里的代码只管接收.
+ //若要返回结果,可在API处理中调用此类对象的SendMessage方法,统一打包发送.不要被微软的示例给迷惑了.
+ } while (token.Buffer.Count > 4);
+ //} while (token.memoryStream.Length > 4);
+ }
//继续接收. 为什么要这么写,请看Socket.ReceiveAsync方法的说明
if (!token.Socket.ReceiveAsync(e))