using System.Net; using System.Net.Sockets; using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Exception; namespace Milimoe.FunGame.Core.Service { internal class SocketManager { #region 属性 /// /// 客户端专用Socket /// internal static Socket? Socket => _Socket; /// /// 服务器端专用Socket /// internal static Socket? ServerSocket => _ServerSocket; private static Socket? _Socket = null; private static Socket? _ServerSocket = null; #endregion #region 实现 /// /// 创建服务器监听Socket /// /// 监听端口号 /// 最大连接数量 /// 服务器端专用Socket internal static Socket? StartListening(int port = 22222, int maxConnection = 0) { if (maxConnection <= 0) maxConnection = SocketSet.MaxConnection_2C2G; try { _ServerSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint ServerEndPoint = new(IPAddress.Any, port); _ServerSocket.Bind(ServerEndPoint); _ServerSocket.Listen(maxConnection); _ServerSocket.NoDelay = true; return _ServerSocket; } catch { ServerSocket?.Close(); } return null; } /// /// 创建一个监听到客户端Socket /// /// 客户端IP地址[0]和客户端Socket[1] internal static object[] Accept() { if (ServerSocket is null) return []; Socket Client; string ClientIP; try { Client = ServerSocket.Accept(); Client.NoDelay = true; ClientIP = Client.RemoteEndPoint?.ToString() ?? "Unknown"; return [ClientIP, Client]; } catch { ServerSocket?.Close(); } return []; } /// /// 创建客户端Socket /// /// 服务器IP地址 /// 服务器监听端口 /// 客户端专用Socket internal static Socket? Connect(string address, int port = 22222) { Socket? ClientSocket; EndPoint ServerEndPoint; try { string IP = NetworkUtility.GetIPAddress(address); ServerEndPoint = new IPEndPoint(IPAddress.Parse(IP), port); if (ServerEndPoint != null) { ClientSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); bool Connecting = true; Task t = Task.Run(() => { while (Connecting) { if (!ClientSocket.Connected && Connecting) { ClientSocket.Connect(ServerEndPoint); if (ClientSocket.Connected) { ClientSocket.NoDelay = true; _Socket = ClientSocket; break; } } } }); if (t.Wait(10 * 1000) && (_Socket?.Connected ?? false)) { return _Socket; } else { Connecting = false; throw new ConnectFailedException(); } } } catch { _Socket?.Close(); } return null; } /// /// 用于服务器端向客户端Socket发送信息 /// /// 客户端Socket /// Socket信息容器 /// 通信结果 internal static SocketResult Send(Socket clientSocket, Library.Common.Network.SocketObject obj) { if (clientSocket != null) { if (clientSocket.Send(General.DefaultEncoding.GetBytes(JsonManager.GetString(obj))) > 0) { return SocketResult.Success; } else return SocketResult.Fail; } return SocketResult.NotSent; } /// /// 用于服务器端向客户端Socket发送信息 [ 异步版 ] /// /// 客户端Socket /// Socket信息容器 /// 通信结果 internal static async Task SendAsync(Socket clientSocket, Library.Common.Network.SocketObject obj) { if (clientSocket != null) { if (await clientSocket.SendAsync(General.DefaultEncoding.GetBytes(JsonManager.GetString(obj))) > 0) { return SocketResult.Success; } else return SocketResult.Fail; } return SocketResult.NotSent; } /// /// 用于客户端向服务器Socket发送信息 /// /// Socket信息容器 /// 通信结果 internal static SocketResult Send(Library.Common.Network.SocketObject obj) { if (Socket != null) { if (Socket.Send(General.DefaultEncoding.GetBytes(JsonManager.GetString(obj))) > 0) { return SocketResult.Success; } else return SocketResult.Fail; } return SocketResult.NotSent; } /// /// 用于客户端向服务器Socket发送信息 [ 异步版 ] /// /// Socket信息容器 /// 通信结果 internal static async Task SendAsync(Library.Common.Network.SocketObject obj) { if (Socket != null) { if (await Socket.SendAsync(General.DefaultEncoding.GetBytes(JsonManager.GetString(obj))) > 0) { return SocketResult.Success; } else return SocketResult.Fail; } return SocketResult.NotSent; } /// /// 接收数据流中的信息 /// 如果是服务器接收信息需要传入客户端Socket /// /// 如果是服务器接收信息需要传入客户端Socket /// SocketObjects internal static Library.Common.Network.SocketObject[] Receive(Socket? clientSocket = null) { try { List result = []; Socket? tempSocket = clientSocket is null ? Socket : clientSocket; if (tempSocket != null) { // 从服务器接收消息 byte[] buffer = new byte[General.SocketByteSize]; int length = tempSocket.Receive(buffer, buffer.Length, SocketFlags.None); string msg = ""; if (length > 0) { msg = General.DefaultEncoding.GetString(buffer, 0, length); if (JsonManager.IsCompleteJson(msg)) { foreach (Library.Common.Network.SocketObject obj in JsonManager.GetObjects(msg)) { result.Add(obj); // 客户端接收消息,广播ScoketObject到每个UIModel if (clientSocket is null) OnSocketReceive(obj); } return [.. result]; } else { Thread.Sleep(20); while (true) { if (tempSocket.Available > 0) { length = tempSocket.Receive(buffer, buffer.Length, SocketFlags.None); msg += General.DefaultEncoding.GetString(buffer, 0, length); if (JsonManager.IsCompleteJson(msg)) { break; } Thread.Sleep(20); } else break; } } } foreach (Library.Common.Network.SocketObject obj in JsonManager.GetObjects(msg)) { result.Add(obj); // 客户端接收消息,广播ScoketObject到每个UIModel if (clientSocket is null) OnSocketReceive(obj); } } return [.. result]; } catch (Exception e) { TXTHelper.AppendErrorLog(e.GetErrorInfo()); return []; } } /// /// 接收数据流中的信息 [ 异步版 ] /// 如果是服务器接收信息需要传入客户端Socket /// /// 如果是服务器接收信息需要传入客户端Socket /// SocketObjects internal static async Task ReceiveAsync(Socket? clientSocket = null) { try { List result = []; Socket? tempSocket = clientSocket is null ? Socket : clientSocket; if (tempSocket != null) { // 从服务器接收消息 byte[] buffer = new byte[General.SocketByteSize]; int length = await tempSocket.ReceiveAsync(new ArraySegment(buffer), SocketFlags.None); string msg = ""; if (length > 0) { msg = General.DefaultEncoding.GetString(buffer, 0, length); if (JsonManager.IsCompleteJson(msg)) { foreach (Library.Common.Network.SocketObject obj in JsonManager.GetObjects(msg)) { result.Add(obj); // 客户端接收消息,广播ScoketObject到每个UIModel if (clientSocket is null) OnSocketReceive(obj); } return [.. result]; } else { Thread.Sleep(20); while (true) { if (tempSocket.Available > 0) { length = tempSocket.Receive(buffer, buffer.Length, SocketFlags.None); msg += General.DefaultEncoding.GetString(buffer, 0, length); if (JsonManager.IsCompleteJson(msg)) { break; } Thread.Sleep(20); } else break; } } } foreach (Library.Common.Network.SocketObject obj in JsonManager.GetObjects(msg)) { result.Add(obj); // 客户端接收消息,广播ScoketObject到每个UIModel if (clientSocket is null) OnSocketReceive(obj); } } return [.. result]; } catch (Exception e) { TXTHelper.AppendErrorLog(e.GetErrorInfo()); return []; } } #endregion #region 事件 /// /// 监听事件的委托 /// /// SocketObject internal delegate void SocketReceiveHandler(Library.Common.Network.SocketObject obj); /// /// 监听事件 /// internal static event SocketReceiveHandler? SocketReceive; /// /// 触发异步监听事件 /// /// SocketObject internal static void OnSocketReceive(Library.Common.Network.SocketObject obj) { SocketReceive?.Invoke(obj); } #endregion } }