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
}
}