fix: 由于解析错误导致的无法通信的问题

This commit is contained in:
SikongJueluo 2025-07-17 14:11:24 +08:00
parent 56dcbf5caa
commit 1053d71d29
No known key found for this signature in database
4 changed files with 99 additions and 107 deletions

View File

@ -14,8 +14,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DotNext" Version="5.19.1" /> <PackageReference Include="DotNext" Version="5.23.0" />
<PackageReference Include="DotNext.Threading" Version="5.19.1" /> <PackageReference Include="DotNext.Threading" Version="5.23.0" />
<PackageReference Include="Honoo.IO.Hashing.Crc" Version="1.3.3" /> <PackageReference Include="Honoo.IO.Hashing.Crc" Version="1.3.3" />
<PackageReference Include="linq2db.AspNet" Version="5.4.1" /> <PackageReference Include="linq2db.AspNet" Version="5.4.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.7" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.7" />

View File

@ -525,9 +525,9 @@ public class UDPClientPool
{ {
var bytes = udpDatas[i].Data; var bytes = udpDatas[i].Data;
var expectedLen = ((pkgList[i].Options.BurstLength + 1) * 4); var expectedLen = ((pkgList[i].Options.BurstLength + 1) * 4);
if ((bytes.Length - 4) != expectedLen) if ((bytes.Length - 8) != expectedLen)
return new(new Exception($"Expected {expectedLen} bytes but received {bytes.Length - 4} bytes at segment {i}")); return new(new Exception($"Expected {expectedLen} bytes but received {bytes.Length - 8} bytes at segment {i}"));
resultData.AddRange(bytes[4..]); resultData.AddRange(bytes[8..]);
} }
// Validate total data length // Validate total data length

View File

@ -6,6 +6,7 @@ using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using Common; using Common;
using DotNext; using DotNext;
using DotNext.Threading;
using Newtonsoft.Json; using Newtonsoft.Json;
using WebProtocol; using WebProtocol;
@ -81,7 +82,7 @@ public class UDPServer
private ConcurrentDictionary<string, SortedList<UInt32, UDPData>> udpData private ConcurrentDictionary<string, SortedList<UInt32, UDPData>> udpData
= new ConcurrentDictionary<string, SortedList<UInt32, UDPData>>(); = new ConcurrentDictionary<string, SortedList<UInt32, UDPData>>();
private readonly ReaderWriterLockSlim udpDataLock = new ReaderWriterLockSlim(); private readonly AsyncReaderWriterLock udpDataLock = new AsyncReaderWriterLock();
private int listenPort; private int listenPort;
private List<UdpClient> listeners = new List<UdpClient>(); private List<UdpClient> listeners = new List<UdpClient>();
@ -189,35 +190,20 @@ public class UDPServer
) )
{ {
UDPData? data = null; UDPData? data = null;
var key = $"{ipAddr}-{taskID}";
var startTime = DateTime.Now;
var isTimeout = false;
while (!isTimeout)
{
var elapsed = DateTime.Now - startTime;
isTimeout = elapsed >= TimeSpan.FromMilliseconds(timeout);
if (isTimeout) break;
udpDataLock.EnterWriteLock();
try try
{ {
var key = $"{ipAddr}-{taskID}"; using (await udpDataLock.AcquireWriteLockAsync(TimeSpan.FromMilliseconds(timeout)))
{
if (udpData.TryGetValue(key, out var sortedList) && sortedList.Count > 0) if (udpData.TryGetValue(key, out var sortedList) && sortedList.Count > 0)
{ {
// 获取最早的数据(第一个元素) // 获取最早的数据(第一个元素)
var firstKey = sortedList.Keys[0]; var firstKey = sortedList.Keys[0];
data = sortedList[firstKey]; data = sortedList[firstKey];
sortedList.RemoveAt(0); sortedList.RemoveAt(0);
break;
} }
} }
finally
{
udpDataLock.ExitWriteLock();
}
await Task.Delay(cycle);
}
if (data is null) if (data is null)
{ {
@ -229,6 +215,12 @@ public class UDPServer
return new(data.DeepClone()); return new(data.DeepClone());
} }
} }
catch
{
logger.Trace("Get nothing even after time out");
return new(null);
}
}
/// <summary> /// <summary>
/// 异步寻找目标发送的所有内容,并清空队列 /// 异步寻找目标发送的所有内容,并清空队列
@ -240,32 +232,20 @@ public class UDPServer
public async ValueTask<Optional<List<UDPData>>> FindDataArrayAsync(string ipAddr, int taskID, int timeout = 1000) public async ValueTask<Optional<List<UDPData>>> FindDataArrayAsync(string ipAddr, int taskID, int timeout = 1000)
{ {
List<UDPData>? data = null; List<UDPData>? data = null;
var key = $"{ipAddr}-{taskID}";
var startTime = DateTime.Now;
var isTimeout = false;
while (!isTimeout)
{
var elapsed = DateTime.Now - startTime;
isTimeout = elapsed >= TimeSpan.FromMilliseconds(timeout);
if (isTimeout) break;
udpDataLock.EnterWriteLock();
try try
{ {
var key = $"{ipAddr}-{taskID}"; using (await udpDataLock.AcquireWriteLockAsync(TimeSpan.FromMilliseconds(timeout)))
{
if (udpData.TryGetValue(key, out var sortedList) && sortedList.Count > 0) if (udpData.TryGetValue(key, out var sortedList) && sortedList.Count > 0)
{ {
data = new List<UDPData>(sortedList.Values); data = new List<UDPData>(sortedList.Values);
// 输出数据 // 输出数据
// PrintDataArray(data); // PrintDataArray(data);
sortedList.Clear(); sortedList.Clear();
break;
}
}
finally
{
udpDataLock.ExitWriteLock();
} }
} }
if (data is null) if (data is null)
@ -278,6 +258,13 @@ public class UDPServer
return new(data); return new(data);
} }
} }
catch
{
logger.Trace("Get nothing even after time out");
return new(null);
}
}
/// <summary> /// <summary>
/// 获取还未被读取的数据列表 /// 获取还未被读取的数据列表
@ -290,28 +277,21 @@ public class UDPServer
{ {
List<UDPData>? data = null; List<UDPData>? data = null;
var startTime = DateTime.Now;
var isTimeout = false;
while (!isTimeout)
{
var elapsed = DateTime.Now - startTime;
isTimeout = elapsed >= TimeSpan.FromMilliseconds(timeout);
if (isTimeout) break;
udpDataLock.EnterReadLock();
try try
{
using (await udpDataLock.AcquireReadLockAsync(TimeSpan.FromMilliseconds(timeout)))
{ {
var key = $"{ipAddr}-{taskID}"; var key = $"{ipAddr}-{taskID}";
if (udpData.TryGetValue(key, out var sortedList) && sortedList.Count > 0) if (udpData.TryGetValue(key, out var sortedList) && sortedList.Count > 0)
{ {
data = new List<UDPData>(sortedList.Values); data = new List<UDPData>(sortedList.Values);
break;
} }
} }
finally }
catch (TimeoutException)
{ {
udpDataLock.ExitReadLock(); logger.Trace("Failed to acquire read lock within timeout");
} return new(null);
} }
if (data is null) if (data is null)
@ -336,28 +316,21 @@ public class UDPServer
{ {
int? count = null; int? count = null;
var startTime = DateTime.Now;
var isTimeout = false;
while (!isTimeout)
{
var elapsed = DateTime.Now - startTime;
isTimeout = elapsed >= TimeSpan.FromMilliseconds(timeout);
if (isTimeout) break;
udpDataLock.EnterReadLock();
try try
{
using (await udpDataLock.AcquireReadLockAsync(TimeSpan.FromMilliseconds(timeout)))
{ {
var key = $"{ipAddr}-{taskID}"; var key = $"{ipAddr}-{taskID}";
if (udpData.TryGetValue(key, out var sortedList)) if (udpData.TryGetValue(key, out var sortedList))
{ {
count = sortedList.Count; count = sortedList.Count;
break;
} }
} }
finally }
catch (TimeoutException)
{ {
udpDataLock.ExitReadLock(); logger.Trace("Failed to acquire read lock within timeout");
} return Optional<int>.None;
} }
if (count is null) if (count is null)
@ -426,7 +399,7 @@ public class UDPServer
private async Task ReceiveHandler(byte[] data, IPEndPoint endPoint, DateTime time) private async Task ReceiveHandler(byte[] data, IPEndPoint endPoint, DateTime time)
{ {
// 异步锁保护 udpData // 异步锁保护 udpData
await Task.Run(() => await Task.Run(async () =>
{ {
try try
{ {
@ -438,7 +411,7 @@ public class UDPServer
return; return;
} }
var udpDataObj = RecordUDPData(data, endPoint, time, Convert.ToInt32(data[1])); var udpDataObj = await RecordUDPData(data, endPoint, time, Convert.ToInt32(data[1 + 4]));
// PrintData(udpDataObj); // PrintData(udpDataObj);
} }
catch (Exception e) catch (Exception e)
@ -448,7 +421,7 @@ public class UDPServer
}); });
} }
private UDPData RecordUDPData(byte[] bytes, IPEndPoint remoteEP, DateTime time, int taskID) private async Task<UDPData> RecordUDPData(byte[] bytes, IPEndPoint remoteEP, DateTime time, int taskID)
{ {
var remoteAddress = remoteEP.Address.ToString(); var remoteAddress = remoteEP.Address.ToString();
var remotePort = remoteEP.Port; var remotePort = remoteEP.Port;
@ -465,8 +438,9 @@ public class UDPServer
var key = $"{remoteAddress}-{taskID}"; var key = $"{remoteAddress}-{taskID}";
udpDataLock.EnterWriteLock();
try try
{
using (await udpDataLock.AcquireWriteLockAsync(TimeSpan.FromMilliseconds(5000)))
{ {
var sortedList = udpData.GetOrAdd(key, _ => new SortedList<UInt32, UDPData>()); var sortedList = udpData.GetOrAdd(key, _ => new SortedList<UInt32, UDPData>());
@ -482,12 +456,12 @@ public class UDPServer
sortedList.Add(uniqueTime, data); sortedList.Add(uniqueTime, data);
// 输出单个数据 // 输出单个数据
PrintData(data); PrintData(data);
// 输出全部数据
// PrintAllData();
} }
finally }
catch (TimeoutException)
{ {
udpDataLock.ExitWriteLock(); logger.Error($"Failed to acquire write lock for recording UDP data from {remoteAddress}:{remotePort}");
throw;
} }
return data; return data;
@ -550,12 +524,13 @@ public class UDPServer
/// 将所有数据输出到log中 /// 将所有数据输出到log中
/// </summary> /// </summary>
/// <returns> void </returns> /// <returns> void </returns>
public void PrintAllData() public async Task PrintAllDataAsync()
{ {
logger.Debug("Ready Data:"); logger.Debug("Ready Data:");
udpDataLock.EnterReadLock();
try try
{
using (await udpDataLock.AcquireReadLockAsync(TimeSpan.FromMilliseconds(5000)))
{ {
foreach (var kvp in udpData) foreach (var kvp in udpData)
{ {
@ -565,9 +540,10 @@ public class UDPServer
} }
} }
} }
finally }
catch (TimeoutException)
{ {
udpDataLock.ExitReadLock(); logger.Error("Failed to acquire read lock for printing all data");
} }
} }
@ -580,18 +556,14 @@ public class UDPServer
public void ClearUDPData(string ipAddr, int taskID) public void ClearUDPData(string ipAddr, int taskID)
{ {
var key = $"{ipAddr}-{taskID}"; var key = $"{ipAddr}-{taskID}";
udpDataLock.EnterWriteLock();
try using (udpDataLock.AcquireWriteLock())
{ {
if (udpData.TryGetValue(key, out var sortedList)) if (udpData.TryGetValue(key, out var sortedList))
{ {
sortedList.Clear(); sortedList.Clear();
} }
} }
finally
{
udpDataLock.ExitWriteLock();
}
// 强制进行ARP刷新防止后续传输时造成影响 // 强制进行ARP刷新防止后续传输时造成影响
// FlushArpEntry(ipAddr); // FlushArpEntry(ipAddr);

View File

@ -393,6 +393,16 @@ namespace WebProtocol
bytes[8..]); bytes[8..]);
} }
/// <summary>
/// [TODO:description]
/// </summary>
/// <param name="bytes">[TODO:parameter]</param>
/// <returns>[TODO:return]</returns>
public static bool IsRecvDataPackage(byte[] bytes)
{
return bytes[4] == (byte)PackSign.RecvData;
}
/// <summary> /// <summary>
/// 将数据包转化为字节数组 /// 将数据包转化为字节数组
/// </summary> /// </summary>
@ -496,6 +506,16 @@ namespace WebProtocol
return new RecvRespPackage(timestamp, bytes[5], bytes[6]); return new RecvRespPackage(timestamp, bytes[5], bytes[6]);
} }
/// <summary>
/// [TODO:description]
/// </summary>
/// <param name="bytes">[TODO:parameter]</param>
/// <returns>[TODO:return]</returns>
public static bool IsRecvRespPackage(byte[] bytes)
{
return bytes[4] == (byte)PackSign.RecvResp;
}
/// <summary> /// <summary>
/// 将数据包转化为字节数组 /// 将数据包转化为字节数组
/// </summary> /// </summary>