Skip to content
This repository was archived by the owner on Jan 25, 2026. It is now read-only.

Commit 9a5f751

Browse files
committed
fix(McPing): 遇到不回复的端口会无限制等待的问题
1 parent ccbdd53 commit 9a5f751

File tree

2 files changed

+23
-11
lines changed

2 files changed

+23
-11
lines changed

Helper/VarInt.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
namespace PCL.Core.Helper;
77

8-
public class VarInt
8+
public static class VarInt
99
{
1010
/// <summary>
1111
/// 将无符号长整数编码为VarInt字节序列
@@ -92,11 +92,11 @@ public static uint DecodeUInt(byte[] bytes, out int readLength)
9292
/// 从流中读取并解码无符号长整数,并将流前进所读取的字节数
9393
/// </summary>
9494
/// <param name="stream">输入流</param>
95-
/// <param name="token"></param>
95+
/// <param name="cancellationToken">要监视取消请求的标记</param>
9696
/// <returns>解码后的64位无符号整数</returns>
9797
/// <exception cref="EndOfStreamException">流提前结束</exception>
9898
/// <exception cref="FormatException">VarInt格式无效</exception>
99-
public async static Task<ulong> ReadFromStream(Stream stream, CancellationToken token = default)
99+
public static async Task<ulong> ReadFromStream(Stream stream, CancellationToken cancellationToken = default)
100100
{
101101
ulong result = 0;
102102
int shift = 0;
@@ -105,7 +105,7 @@ public async static Task<ulong> ReadFromStream(Stream stream, CancellationToken
105105
var buffer = new byte[1];
106106
while (true)
107107
{
108-
int readLength = await stream.ReadAsync(buffer, 0, 1, token);
108+
int readLength = await stream.ReadAsync(buffer, 0, 1, cancellationToken);
109109
if (readLength == 0)
110110
throw new EndOfStreamException();
111111

@@ -128,11 +128,11 @@ public async static Task<ulong> ReadFromStream(Stream stream, CancellationToken
128128
/// 从流中读取并解码无符号整数,并将流前进所读取的字节数
129129
/// </summary>
130130
/// <param name="stream">输入流</param>
131-
/// <param name="token"></param>
131+
/// <param name="cancellationToken"></param>
132132
/// <returns>解码后的32位无符号整数</returns>
133-
public async static Task<uint> ReadUIntFromStream(Stream stream, CancellationToken token = default)
133+
public static async Task<uint> ReadUIntFromStream(Stream stream, CancellationToken cancellationToken = default)
134134
{
135-
ulong result = await ReadFromStream(stream, token);
135+
ulong result = await ReadFromStream(stream, cancellationToken);
136136
if (result > uint.MaxValue)
137137
throw new OverflowException("Decoded value exceeds UInt32 range");
138138
return (uint)result;

Utils/Minecraft/McPing.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,25 @@ public class McPing : IDisposable
2121
private readonly string _host;
2222
private readonly Socket _socket;
2323
private const int DefaultTimeout = 10000;
24+
private int _timeout;
2425

25-
public McPing(IPEndPoint endpoint)
26+
public McPing(IPEndPoint endpoint, int timeout = DefaultTimeout)
2627
{
2728
_endpoint = endpoint;
2829
_host = _endpoint.Address.ToString();
2930
_socket =new Socket(SocketType.Stream, ProtocolType.Tcp);
31+
_timeout = timeout;
3032
}
3133

32-
public McPing(string ip, int port = 25565)
34+
public McPing(string ip, int port = 25565, int timeout = DefaultTimeout)
3335
{
3436
if (IPAddress.TryParse(ip, out var ipAddress))
3537
_endpoint = new IPEndPoint(ipAddress, port);
3638
else
3739
_endpoint = new IPEndPoint(Dns.GetHostAddresses(ip).First(), port);
3840
_host = ip;
3941
_socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
42+
_timeout = timeout;
4043
}
4144

4245
/// <summary>
@@ -47,7 +50,16 @@ public McPing(string ip, int port = 25565)
4750
public async Task<McPingResult> PingAsync()
4851
{
4952
using var cts = new CancellationTokenSource();
50-
cts.CancelAfter(DefaultTimeout);
53+
cts.CancelAfter(_timeout);
54+
// 注册超时回调:强制关闭Socket中断阻塞操作
55+
cts.Token.Register(() =>
56+
{
57+
try
58+
{
59+
if (_socket?.Connected == true) _socket.Close(); // 强制关闭连接,中断 ReadAsync 阻塞
60+
}
61+
catch (ObjectDisposedException) { /* 忽略已释放的异常 */ }
62+
});
5163
// 信息获取
5264
LogWrapper.Debug("McPing",$"Connecting to {_endpoint}");
5365
await _socket.ConnectAsync(_endpoint);
@@ -260,6 +272,6 @@ public void Dispose()
260272
if (_disposed) return;
261273
_disposed = true;
262274
GC.SuppressFinalize(this);
263-
_socket.Dispose();
275+
_socket?.Dispose();
264276
}
265277
}

0 commit comments

Comments
 (0)