支持使用域名连接服务器;添加了连接10秒强制超时检测

This commit is contained in:
milimoe 2024-01-16 23:40:33 +08:00
parent 3a46511bc0
commit 0121c42ac7
Signed by: milimoe
GPG Key ID: 05D280912DA6C69E
10 changed files with 127 additions and 54 deletions

View File

@ -1,4 +1,5 @@
using System.Collections; using System.Collections;
using System.Net;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
@ -56,30 +57,42 @@ namespace Milimoe.FunGame.Core.Api.Utility
} }
/// <summary> /// <summary>
/// 判断字符串是否是一个FunGame可接受的服务器地址 /// 判断字符串是否是一个FunGame可接受的服务器地址<para/>
/// 此方法可以解析域名
/// </summary> /// </summary>
/// <param name="str"></param> /// <param name="str"></param>
/// <returns></returns> /// <param name="addr"></param>
public static ErrorIPAddressType IsServerAddress(string str) /// <param name="port"></param>
/// <returns>返回地址验证结果,同时输出服务器地址和端口号</returns>
public static ErrorIPAddressType IsServerAddress(string str, out string addr, out int port)
{ {
string[] strs = str.Split(':'); addr = "";
port = 22222;
string ip; string ip;
int port; // 包含端口号时,需要先截取
if (strs.Length < 2) string[] strs = str.Split(':');
if (strs.Length == 1)
{
addr = str;
}
else if (strs.Length > 1)
{
addr = strs[0];
port = int.Parse(strs[1]);
}
else if (strs.Length > 2)
{
return ErrorIPAddressType.WrongFormat;
}
try
{
ip = GetIPAddress(addr);
}
catch
{ {
ip = strs[0]; ip = strs[0];
port = 22222;
} }
else if (strs.Length < 3) return IsServerAddress(ip, port);
{
ip = strs[0];
port = Convert.ToInt32(strs[1]);
}
else return ErrorIPAddressType.WrongFormat;
if (IsIP(ip) && port > 0 && port < 65536) return ErrorIPAddressType.None;
else if (!IsIP(ip) && port > 0 && port < 65536) return ErrorIPAddressType.IsNotIP;
else if (IsIP(ip) && (port <= 0 || port >= 65536)) return ErrorIPAddressType.IsNotPort;
else return ErrorIPAddressType.WrongFormat;
} }
/// <summary> /// <summary>
@ -90,9 +103,21 @@ namespace Milimoe.FunGame.Core.Api.Utility
/// <returns></returns> /// <returns></returns>
public static ErrorIPAddressType IsServerAddress(string ip, int port) public static ErrorIPAddressType IsServerAddress(string ip, int port)
{ {
if (IsIP(ip) && port > 0 && port < 65536) return ErrorIPAddressType.None; if (IsIP(ip))
else if (!IsIP(ip) && port > 0 && port < 65536) return ErrorIPAddressType.IsNotIP; {
else if (IsIP(ip) && (port <= 0 || port >= 65536)) return ErrorIPAddressType.IsNotPort; if (port > 0 && port < 65536)
{
return ErrorIPAddressType.None;
}
else
{
return ErrorIPAddressType.IsNotPort;
}
}
else if (port > 0 && port < 65536)
{
return ErrorIPAddressType.IsNotAddress;
}
else return ErrorIPAddressType.WrongFormat; else return ErrorIPAddressType.WrongFormat;
} }
@ -119,6 +144,20 @@ namespace Milimoe.FunGame.Core.Api.Utility
return -1; return -1;
} }
/// <summary>
/// 解析域名为IP地址
/// </summary>
/// <param name="domain"></param>
/// <param name="family"></param>
/// <returns></returns>
internal static string GetIPAddress(string domain, System.Net.Sockets.AddressFamily family = System.Net.Sockets.AddressFamily.InterNetwork)
{
// 如果是域名则解析为IP地址
IPHostEntry entrys = Dns.GetHostEntry(domain);
// 这里使用断言请自行添加try catch配合使用
return entrys.AddressList.Where(addr => addr.AddressFamily == family).FirstOrDefault()!.ToString();
}
/// <summary> /// <summary>
/// 返回目标对象的Json字符串 /// 返回目标对象的Json字符串
/// </summary> /// </summary>

View File

@ -81,13 +81,13 @@ namespace Milimoe.FunGame.Core.Controller
/// <summary> /// <summary>
/// 连接服务器 /// 连接服务器
/// </summary> /// </summary>
/// <param name="ip"></param> /// <param name="addr"></param>
/// <param name="port"></param> /// <param name="port"></param>
/// <returns></returns> /// <returns></returns>
public ConnectResult Connect(string ip, int port) public ConnectResult Connect(string addr, int port)
{ {
ArrayList ConnectArgs = []; ArrayList ConnectArgs = [];
if (!BeforeConnect(ref ip, ref port, ConnectArgs)) if (!BeforeConnect(ref addr, ref port, ConnectArgs))
{ {
return ConnectResult.ConnectFailed; return ConnectResult.ConnectFailed;
} }
@ -98,7 +98,7 @@ namespace Milimoe.FunGame.Core.Controller
string notice = ""; string notice = "";
// 检查服务器IP地址和端口是否正确 // 检查服务器IP地址和端口是否正确
if (ip == "" || port <= 0) if (addr == "" || port <= 0)
{ {
result = ConnectResult.FindServerFailed; result = ConnectResult.FindServerFailed;
} }
@ -106,7 +106,7 @@ namespace Milimoe.FunGame.Core.Controller
{ {
// 与服务器建立连接 // 与服务器建立连接
_Socket?.Close(); _Socket?.Close();
_Socket = Socket.Connect(ip, port); _Socket = Socket.Connect(addr, port);
if (_Socket != null && _Socket.Connected) if (_Socket != null && _Socket.Connected)
{ {
if (_Socket.Send(SocketMessageType.Connect, ConnectArgs.Cast<object>().ToArray()) == SocketResult.Success) if (_Socket.Send(SocketMessageType.Connect, ConnectArgs.Cast<object>().ToArray()) == SocketResult.Success)

View File

@ -428,12 +428,15 @@
<param name="str"></param> <param name="str"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:Milimoe.FunGame.Core.Api.Utility.NetworkUtility.IsServerAddress(System.String)"> <member name="M:Milimoe.FunGame.Core.Api.Utility.NetworkUtility.IsServerAddress(System.String,System.String@,System.Int32@)">
<summary> <summary>
判断字符串是否是一个FunGame可接受的服务器地址 判断字符串是否是一个FunGame可接受的服务器地址<para/>
此方法可以解析域名
</summary> </summary>
<param name="str"></param> <param name="str"></param>
<returns></returns> <param name="addr"></param>
<param name="port"></param>
<returns>返回地址验证结果,同时输出服务器地址和端口号</returns>
</member> </member>
<member name="M:Milimoe.FunGame.Core.Api.Utility.NetworkUtility.IsServerAddress(System.String,System.Int32)"> <member name="M:Milimoe.FunGame.Core.Api.Utility.NetworkUtility.IsServerAddress(System.String,System.Int32)">
<summary> <summary>
@ -450,6 +453,14 @@
<param name="addr">服务器IP地址</param> <param name="addr">服务器IP地址</param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:Milimoe.FunGame.Core.Api.Utility.NetworkUtility.GetIPAddress(System.String,System.Net.Sockets.AddressFamily)">
<summary>
解析域名为IP地址
</summary>
<param name="domain"></param>
<param name="family"></param>
<returns></returns>
</member>
<member name="M:Milimoe.FunGame.Core.Api.Utility.NetworkUtility.JsonSerialize``1(``0)"> <member name="M:Milimoe.FunGame.Core.Api.Utility.NetworkUtility.JsonSerialize``1(``0)">
<summary> <summary>
返回目标对象的Json字符串 返回目标对象的Json字符串
@ -1086,7 +1097,7 @@
<summary> <summary>
连接服务器 连接服务器
</summary> </summary>
<param name="ip"></param> <param name="addr"></param>
<param name="port"></param> <param name="port"></param>
<returns></returns> <returns></returns>
</member> </member>
@ -2322,9 +2333,9 @@
<param name="GamingType"></param> <param name="GamingType"></param>
<param name="Data"></param> <param name="Data"></param>
</member> </member>
<member name="P:Milimoe.FunGame.Core.Model.Session.Server_IP"> <member name="P:Milimoe.FunGame.Core.Model.Session.Server_Address">
<summary> <summary>
服务器IP地址 服务器地址
</summary> </summary>
</member> </member>
<member name="P:Milimoe.FunGame.Core.Model.Session.Server_Port"> <member name="P:Milimoe.FunGame.Core.Model.Session.Server_Port">
@ -2657,7 +2668,7 @@
<summary> <summary>
创建客户端Socket 创建客户端Socket
</summary> </summary>
<param name="IP">服务器IP地址</param> <param name="Address">服务器IP地址</param>
<param name="Port">服务器监听端口</param> <param name="Port">服务器监听端口</param>
<returns>客户端专用Socket</returns> <returns>客户端专用Socket</returns>
</member> </member>
@ -2736,5 +2747,14 @@
<param name="action"></param> <param name="action"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:Milimoe.FunGame.Core.Service.TaskExtension.WithCancellation(System.Threading.Tasks.Task,System.Threading.CancellationToken)">
<summary>
用于取消任务
</summary>
<param name="task"></param>
<param name="cancellationToken"></param>
<returns></returns>
<exception cref="T:System.OperationCanceledException"></exception>
</member>
</members> </members>
</doc> </doc>

View File

@ -7,7 +7,7 @@ namespace Milimoe.FunGame.Core.Interface.Base
public System.Net.Sockets.Socket Instance { get; } public System.Net.Sockets.Socket Instance { get; }
public SocketRuntimeType Runtime { get; } public SocketRuntimeType Runtime { get; }
public Guid Token { get; } public Guid Token { get; }
public string ServerIP { get; } public string ServerAddress { get; }
public int ServerPort { get; } public int ServerPort { get; }
public string ServerName { get; } public string ServerName { get; }
public string ServerNotice { get; } public string ServerNotice { get; }

View File

@ -9,7 +9,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
public System.Net.Sockets.Socket Instance { get; } public System.Net.Sockets.Socket Instance { get; }
public SocketRuntimeType Runtime => SocketRuntimeType.Server; public SocketRuntimeType Runtime => SocketRuntimeType.Server;
public Guid Token { get; } = Guid.Empty; public Guid Token { get; } = Guid.Empty;
public string ServerIP { get; } = ""; public string ServerAddress { get; } = "";
public int ServerPort { get; } = 0; public int ServerPort { get; } = 0;
public string ServerName { get; } = ""; public string ServerName { get; } = "";
public string ServerNotice { get; } = ""; public string ServerNotice { get; } = "";

View File

@ -9,7 +9,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
public System.Net.Sockets.Socket Instance { get; } public System.Net.Sockets.Socket Instance { get; }
public SocketRuntimeType Runtime => SocketRuntimeType.Server; public SocketRuntimeType Runtime => SocketRuntimeType.Server;
public Guid Token { get; } = Guid.Empty; public Guid Token { get; } = Guid.Empty;
public string ServerIP { get; } = ""; public string ServerAddress { get; } = "";
public int ServerPort { get; } = 0; public int ServerPort { get; } = 0;
public string ServerName { get; } = ""; public string ServerName { get; } = "";
public string ServerNotice { get; } = ""; public string ServerNotice { get; } = "";

View File

@ -10,7 +10,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
public System.Net.Sockets.Socket Instance { get; } public System.Net.Sockets.Socket Instance { get; }
public SocketRuntimeType Runtime => SocketRuntimeType.Client; public SocketRuntimeType Runtime => SocketRuntimeType.Client;
public Guid Token { get; set; } = Guid.Empty; public Guid Token { get; set; } = Guid.Empty;
public string ServerIP { get; } = ""; public string ServerAddress { get; } = "";
public int ServerPort { get; } = 0; public int ServerPort { get; } = 0;
public string ServerName { get; } = ""; public string ServerName { get; } = "";
public string ServerNotice { get; } = ""; public string ServerNotice { get; } = "";
@ -27,18 +27,18 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
private bool _SendingHeartBeat = false; private bool _SendingHeartBeat = false;
private int _HeartBeatFaileds = 0; private int _HeartBeatFaileds = 0;
private Socket(System.Net.Sockets.Socket Instance, string ServerIP, int ServerPort) private Socket(System.Net.Sockets.Socket Instance, string ServerAddress, int ServerPort)
{ {
this.Instance = Instance; this.Instance = Instance;
this.ServerIP = ServerIP; this.ServerAddress = ServerAddress;
this.ServerPort = ServerPort; this.ServerPort = ServerPort;
this.StartSendingHeartBeat(); this.StartSendingHeartBeat();
} }
public static Socket Connect(string IP, int Port = 22222) public static Socket Connect(string Address, int Port = 22222)
{ {
System.Net.Sockets.Socket? socket = SocketManager.Connect(IP, Port); System.Net.Sockets.Socket? socket = SocketManager.Connect(Address, Port);
if (socket != null) return new Socket(socket, IP, Port); if (socket != null) return new Socket(socket, Address, Port);
else throw new ConnectFailedException(); else throw new ConnectFailedException();
} }

View File

@ -145,7 +145,7 @@ namespace Milimoe.FunGame.Core.Library.Constant
public enum ErrorIPAddressType public enum ErrorIPAddressType
{ {
None, None,
IsNotIP, IsNotAddress,
IsNotPort, IsNotPort,
WrongFormat WrongFormat
} }

View File

@ -6,9 +6,9 @@ namespace Milimoe.FunGame.Core.Model
public class Session public class Session
{ {
/// <summary> /// <summary>
/// 服务器IP地址 /// 服务器地址
/// </summary> /// </summary>
public string Server_IP { get; set; } = ""; public string Server_Address { get; set; } = "";
/// <summary> /// <summary>
/// 服务器端口号 /// 服务器端口号

View File

@ -77,31 +77,45 @@ namespace Milimoe.FunGame.Core.Service
/// <summary> /// <summary>
/// 创建客户端Socket /// 创建客户端Socket
/// </summary> /// </summary>
/// <param name="IP">服务器IP地址</param> /// <param name="Address">服务器IP地址</param>
/// <param name="Port">服务器监听端口</param> /// <param name="Port">服务器监听端口</param>
/// <returns>客户端专用Socket</returns> /// <returns>客户端专用Socket</returns>
internal static Socket? Connect(string IP, int Port = 22222) internal static Socket? Connect(string Address, int Port = 22222)
{ {
Socket? ClientSocket; Socket? ClientSocket;
EndPoint ServerEndPoint; EndPoint ServerEndPoint;
try try
{ {
ClientSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); string IP = Api.Utility.NetworkUtility.GetIPAddress(Address);
ServerEndPoint = new IPEndPoint(IPAddress.Parse(IP), Port); ServerEndPoint = new IPEndPoint(IPAddress.Parse(IP), Port);
if (ServerEndPoint != null) if (ServerEndPoint != null)
{ {
while (true) ClientSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
bool Connecting = true;
Task t = Task.Run(() =>
{ {
if (!ClientSocket.Connected) while (Connecting)
{ {
ClientSocket.Connect(ServerEndPoint); if (!ClientSocket.Connected && Connecting)
if (ClientSocket.Connected)
{ {
ClientSocket.NoDelay = true; ClientSocket.Connect(ServerEndPoint);
_Socket = ClientSocket; if (ClientSocket.Connected)
return _Socket; {
ClientSocket.NoDelay = true;
_Socket = ClientSocket;
break;
}
} }
} }
});
if (t.Wait(10 * 1000) && (_Socket?.Connected ?? false))
{
return _Socket;
}
else
{
Connecting = false;
throw new ConnectFailedException();
} }
} }
} }