using System.Net; using System.Net.Sockets; using Milimoe.FunGame.Core.Library.Constant; 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; IPEndPoint? ClientIPEndPoint = (IPEndPoint?)Client.RemoteEndPoint; ClientIP = (ClientIPEndPoint != null) ? ClientIPEndPoint.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 = Api.Utility.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 SocketObject) { if (ClientSocket != null) { if (ClientSocket.Send(General.DefaultEncoding.GetBytes(JsonManager.GetString(SocketObject))) > 0) { return SocketResult.Success; } else return SocketResult.Fail; } return SocketResult.NotSent; } /// /// 用于客户端向服务器Socket发送信息 /// /// Socket信息容器 /// 通信结果 internal static SocketResult Send(Library.Common.Network.SocketObject SocketObject) { if (Socket != null) { if (Socket.Send(General.DefaultEncoding.GetBytes(JsonManager.GetString(SocketObject))) > 0) { return SocketResult.Success; } else return SocketResult.Fail; } return SocketResult.NotSent; } /// /// 接收数据流中的信息 /// 如果是服务器接收信息需要传入客户端Socket /// /// 如果是服务器接收信息需要传入客户端Socket /// SocketObjects internal static Library.Common.Network.SocketObject[] Receive(Socket? ClientSocket = null) { 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]; } #endregion #region 事件 /// /// 监听事件的委托 /// /// SocketObject internal delegate void SocketReceiveHandler(Library.Common.Network.SocketObject SocketObject); /// /// 监听事件 /// internal static event SocketReceiveHandler? SocketReceive; /// /// 触发异步监听事件 /// /// SocketObject internal static void OnSocketReceive(Library.Common.Network.SocketObject SocketObject) { SocketReceive?.Invoke(SocketObject); } #endregion } }