fix: 由于解析错误导致的无法通信的问题
This commit is contained in:
parent
56dcbf5caa
commit
1053d71d29
|
@ -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" />
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue