支持使用域名连接服务器;添加了连接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.Net;
using System.Net.NetworkInformation;
using System.Security.Cryptography;
using System.Text;
@ -56,30 +57,42 @@ namespace Milimoe.FunGame.Core.Api.Utility
}
/// <summary>
/// 判断字符串是否是一个FunGame可接受的服务器地址
/// 判断字符串是否是一个FunGame可接受的服务器地址<para/>
/// 此方法可以解析域名
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static ErrorIPAddressType IsServerAddress(string str)
/// <param name="addr"></param>
/// <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;
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];
port = 22222;
}
else if (strs.Length < 3)
{
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;
return IsServerAddress(ip, port);
}
/// <summary>
@ -90,9 +103,21 @@ namespace Milimoe.FunGame.Core.Api.Utility
/// <returns></returns>
public static ErrorIPAddressType IsServerAddress(string ip, int port)
{
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;
if (IsIP(ip))
{
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;
}
@ -119,6 +144,20 @@ namespace Milimoe.FunGame.Core.Api.Utility
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>
/// 返回目标对象的Json字符串
/// </summary>

View File

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

View File

@ -428,12 +428,15 @@
<param name="str"></param>
<returns></returns>
</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>
判断字符串是否是一个FunGame可接受的服务器地址
判断字符串是否是一个FunGame可接受的服务器地址<para/>
此方法可以解析域名
</summary>
<param name="str"></param>
<returns></returns>
<param name="addr"></param>
<param name="port"></param>
<returns>返回地址验证结果,同时输出服务器地址和端口号</returns>
</member>
<member name="M:Milimoe.FunGame.Core.Api.Utility.NetworkUtility.IsServerAddress(System.String,System.Int32)">
<summary>
@ -450,6 +453,14 @@
<param name="addr">服务器IP地址</param>
<returns></returns>
</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)">
<summary>
返回目标对象的Json字符串
@ -1086,7 +1097,7 @@
<summary>
连接服务器
</summary>
<param name="ip"></param>
<param name="addr"></param>
<param name="port"></param>
<returns></returns>
</member>
@ -2322,9 +2333,9 @@
<param name="GamingType"></param>
<param name="Data"></param>
</member>
<member name="P:Milimoe.FunGame.Core.Model.Session.Server_IP">
<member name="P:Milimoe.FunGame.Core.Model.Session.Server_Address">
<summary>
服务器IP地址
服务器地址
</summary>
</member>
<member name="P:Milimoe.FunGame.Core.Model.Session.Server_Port">
@ -2657,7 +2668,7 @@
<summary>
创建客户端Socket
</summary>
<param name="IP">服务器IP地址</param>
<param name="Address">服务器IP地址</param>
<param name="Port">服务器监听端口</param>
<returns>客户端专用Socket</returns>
</member>
@ -2736,5 +2747,14 @@
<param name="action"></param>
<returns></returns>
</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>
</doc>

View File

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

View File

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

View File

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

View File

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