change udpData type from list to queue
This commit is contained in:
@@ -2,7 +2,7 @@ using DotNext;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
class NumberProcessor
|
||||
public class NumberProcessor
|
||||
{
|
||||
public static Result<byte[]> NumberToBytes(ulong num, uint length, bool isRightHigh = false)
|
||||
{
|
||||
|
@@ -68,11 +68,17 @@ public class UDPServer
|
||||
{
|
||||
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
private static Dictionary<string, Queue<UDPData>> udpData = new Dictionary<string, Queue<UDPData>>();
|
||||
|
||||
private int listenPort;
|
||||
private UdpClient listener;
|
||||
private IPEndPoint groupEP;
|
||||
private Dictionary<string, List<UDPData>> udpData = new Dictionary<string, List<UDPData>>();
|
||||
private AsyncReaderWriterLock udpDataLock = new AsyncReaderWriterLock(1);
|
||||
|
||||
private bool isRunning = false;
|
||||
/// <summary>
|
||||
/// 是否正在工作
|
||||
/// </summary>
|
||||
public bool IsRunning { get { return isRunning; } }
|
||||
|
||||
/// <summary>
|
||||
/// Construct a udp server with fixed port
|
||||
@@ -98,55 +104,6 @@ public class UDPServer
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find UDP Receive Data According to ip address
|
||||
/// </summary>
|
||||
/// <param name="ipAddr"> IP Address</param>
|
||||
/// <param name="timeout"> Read and Write Wait for Milliseconds </param>
|
||||
/// <param name="callerName">调用函数名称</param>
|
||||
/// <param name="callerLineNum">调用函数位置</param>
|
||||
/// <returns>UDP Data</returns>
|
||||
public Optional<UDPData> FindData(
|
||||
string ipAddr, int timeout = 1000,
|
||||
[CallerMemberName] string callerName = "",
|
||||
[CallerLineNumber] int callerLineNum = 0)
|
||||
{
|
||||
UDPData? data = null;
|
||||
|
||||
logger.Debug($"Caller \"{callerName}|{callerLineNum}\": Try to find {ipAddr} UDP Data");
|
||||
|
||||
var startTime = DateTime.Now;
|
||||
var isTimeout = false;
|
||||
var timeleft = TimeSpan.FromMilliseconds(timeout);
|
||||
while (!isTimeout)
|
||||
{
|
||||
|
||||
using (udpDataLock.AcquireWriteLock(timeleft))
|
||||
{
|
||||
if (udpData.ContainsKey(ipAddr) && udpData[ipAddr].Count > 0)
|
||||
{
|
||||
data = udpData[ipAddr][0].DeepClone();
|
||||
udpData[ipAddr].RemoveAt(0);
|
||||
logger.Debug($"Find UDP Data: {data.ToString()}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
timeleft = DateTime.Now.Subtract(startTime);
|
||||
isTimeout = timeleft >= TimeSpan.FromMilliseconds(timeout);
|
||||
}
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
logger.Trace("Get nothing even after time out");
|
||||
return Optional.None<UDPData>();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Optional.Some((UDPData)data.DeepClone());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步寻找目标发送的内容
|
||||
/// </summary>
|
||||
@@ -173,20 +130,21 @@ public class UDPServer
|
||||
var timeleft = TimeSpan.FromMilliseconds(timeout);
|
||||
while (!isTimeout)
|
||||
{
|
||||
var elapsed = DateTime.Now - startTime;
|
||||
isTimeout = elapsed >= TimeSpan.FromMilliseconds(timeout);
|
||||
timeleft = TimeSpan.FromMilliseconds(timeout) - elapsed;
|
||||
|
||||
using (await udpDataLock.AcquireWriteLockAsync(timeleft))
|
||||
using (await udpData.AcquireWriteLockAsync(timeleft))
|
||||
{
|
||||
if (udpData.ContainsKey(ipAddr) && udpData[ipAddr].Count > 0)
|
||||
if (udpData.TryGetValue(ipAddr, out var dataQueue) && dataQueue != null && dataQueue.Count > 0)
|
||||
{
|
||||
data = udpData[ipAddr][0].DeepClone();
|
||||
udpData[ipAddr].RemoveAt(0);
|
||||
data = dataQueue.Dequeue();
|
||||
// data = dataList[0].DeepClone();
|
||||
// dataList.RemoveAt(0);
|
||||
logger.Debug($"Find UDP Data: {data.ToString()}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
timeleft = DateTime.Now.Subtract(startTime);
|
||||
isTimeout = timeleft >= TimeSpan.FromMilliseconds(timeout);
|
||||
}
|
||||
|
||||
if (data is null)
|
||||
@@ -215,19 +173,19 @@ public class UDPServer
|
||||
var timeleft = TimeSpan.FromMilliseconds(timeout);
|
||||
while (!isTimeout)
|
||||
{
|
||||
var elapsed = DateTime.Now - startTime;
|
||||
isTimeout = elapsed >= TimeSpan.FromMilliseconds(timeout);
|
||||
timeleft = TimeSpan.FromMilliseconds(timeout) - elapsed;
|
||||
|
||||
using (await udpDataLock.AcquireReadLockAsync(timeleft))
|
||||
using (await udpData.AcquireReadLockAsync(timeleft))
|
||||
{
|
||||
if (udpData.ContainsKey(ipAddr))
|
||||
if (udpData.TryGetValue(ipAddr, out var dataQueue) && dataQueue != null && dataQueue.Count > 0)
|
||||
{
|
||||
data = udpData[ipAddr];
|
||||
logger.Debug($"Find UDP Data Array: {data.ToString()}");
|
||||
data = dataQueue.ToList();
|
||||
logger.Debug($"Find UDP Data Array: {JsonConvert.SerializeObject(data)}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
timeleft = DateTime.Now.Subtract(startTime);
|
||||
isTimeout = timeleft >= TimeSpan.FromMilliseconds(timeout);
|
||||
}
|
||||
|
||||
if (data is null)
|
||||
@@ -249,14 +207,14 @@ public class UDPServer
|
||||
/// <param name="timeout">超时时间范围</param>
|
||||
/// <returns>接收响应包</returns>
|
||||
public async ValueTask<Result<WebProtocol.RecvRespPackage>> WaitForAckAsync
|
||||
(string address, int port, int timeout = 1000)
|
||||
(string address, int port = -1, int timeout = 1000)
|
||||
{
|
||||
var data = await FindDataAsync(address, timeout);
|
||||
if (!data.HasValue)
|
||||
throw new Exception("Get None even after time out!");
|
||||
|
||||
var recvData = data.Value;
|
||||
if (recvData.Address != address || recvData.Port != port)
|
||||
if (recvData.Address != address || (port >= 0 && recvData.Port != port))
|
||||
throw new Exception("Receive Data From Wrong Board!");
|
||||
|
||||
var retPack = WebProtocol.RecvRespPackage.FromBytes(recvData.Data);
|
||||
@@ -274,14 +232,14 @@ public class UDPServer
|
||||
/// <param name="timeout">超时时间范围</param>
|
||||
/// <returns>接收数据包</returns>
|
||||
public async ValueTask<Result<WebProtocol.RecvDataPackage>> WaitForDataAsync
|
||||
(string address, int port, int timeout = 1000)
|
||||
(string address, int port = -1, int timeout = 1000)
|
||||
{
|
||||
var data = await FindDataAsync(address, timeout);
|
||||
if (!data.HasValue)
|
||||
throw new Exception("Get None even after time out!");
|
||||
|
||||
var recvData = data.Value;
|
||||
if (recvData.Address != address || recvData.Port != port)
|
||||
if (recvData.Address != address || (port >= 0 && recvData.Port != port))
|
||||
throw new Exception("Receive Data From Wrong Board!");
|
||||
|
||||
var retPack = WebProtocol.RecvDataPackage.FromBytes(recvData.Data);
|
||||
@@ -307,7 +265,8 @@ public class UDPServer
|
||||
|
||||
|
||||
// Handle Package
|
||||
PrintData(RecordUDPData(bytes, remoteEP));
|
||||
var udpData = RecordUDPData(bytes, remoteEP);
|
||||
PrintData(udpData);
|
||||
|
||||
BEGIN_RECEIVE:
|
||||
listener.BeginReceive(new AsyncCallback(ReceiveHandler), null);
|
||||
@@ -332,36 +291,41 @@ public class UDPServer
|
||||
|
||||
private UDPData RecordUDPData(byte[] bytes, IPEndPoint remoteEP)
|
||||
{
|
||||
using (udpDataLock.AcquireWriteLock())
|
||||
var remoteAddress = remoteEP.Address.ToString();
|
||||
var remotePort = remoteEP.Port;
|
||||
var data = new UDPData()
|
||||
{
|
||||
var remoteAddress = remoteEP.Address.ToString();
|
||||
var remotePort = remoteEP.Port;
|
||||
var data = new UDPData()
|
||||
{
|
||||
Address = remoteAddress,
|
||||
Port = remotePort,
|
||||
Data = bytes,
|
||||
DateTime = DateTime.Now,
|
||||
HasRead = false,
|
||||
};
|
||||
Address = remoteAddress,
|
||||
Port = remotePort,
|
||||
Data = bytes,
|
||||
DateTime = DateTime.Now,
|
||||
HasRead = false,
|
||||
};
|
||||
|
||||
using (udpData.AcquireWriteLock())
|
||||
{
|
||||
// Record UDP Receive Data
|
||||
if (udpData.ContainsKey(remoteAddress))
|
||||
// if (udpData.ContainsKey(remoteAddress))
|
||||
if (udpData.TryGetValue(remoteAddress, out var dataQueue))
|
||||
{
|
||||
var listData = udpData[remoteAddress];
|
||||
listData.Add(data);
|
||||
// var listData = udpData[remoteAddress];
|
||||
// listData.Add(data);
|
||||
dataQueue.Enqueue(data);
|
||||
logger.Trace("Receive data from old client");
|
||||
}
|
||||
else
|
||||
{
|
||||
var list = new List<UDPData>();
|
||||
list.Add(data);
|
||||
udpData.Add(remoteAddress, list);
|
||||
// var list = new List<UDPData>();
|
||||
// list.Add(data);
|
||||
// udpData.Add(remoteAddress, list);
|
||||
var queue = new Queue<UDPData>();
|
||||
queue.Enqueue(data);
|
||||
udpData.Add(remoteAddress, queue);
|
||||
logger.Trace("Receive data from new client");
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -414,7 +378,7 @@ public class UDPServer
|
||||
/// <returns> void </returns>
|
||||
public void PrintAllData()
|
||||
{
|
||||
using (udpDataLock.AcquireReadLock())
|
||||
using (udpData.AcquireReadLock())
|
||||
{
|
||||
logger.Debug("Ready Data:");
|
||||
|
||||
@@ -436,7 +400,7 @@ public class UDPServer
|
||||
{
|
||||
try
|
||||
{
|
||||
listener.BeginReceive(new AsyncCallback(ReceiveHandler), null);
|
||||
this.listener.BeginReceive(new AsyncCallback(ReceiveHandler), null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -444,7 +408,7 @@ public class UDPServer
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
this.isRunning = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,7 +418,8 @@ public class UDPServer
|
||||
/// <returns>None</returns>
|
||||
public void Stop()
|
||||
{
|
||||
listener.Close();
|
||||
this.listener.Close();
|
||||
this.isRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -375,7 +375,7 @@ namespace WebProtocol
|
||||
{
|
||||
if (bytes[0] != (byte)PackSign.RecvData)
|
||||
throw new ArgumentException(
|
||||
"The sign of bytes is not RecvData Package!",
|
||||
$"The sign of bytes is not RecvData Package, Sign: 0x{BitConverter.ToString([bytes[0]])}",
|
||||
nameof(bytes)
|
||||
);
|
||||
return new RecvDataPackage(bytes[1], bytes[2], bytes[4..]);
|
||||
@@ -478,7 +478,7 @@ namespace WebProtocol
|
||||
{
|
||||
if (bytes[0] != (byte)PackSign.RecvResp)
|
||||
throw new ArgumentException(
|
||||
"The sign of bytes is not RecvResp Package!",
|
||||
$"The sign of bytes is not RecvResp Package, Sign: 0x{BitConverter.ToString([bytes[0]])}",
|
||||
nameof(bytes)
|
||||
);
|
||||
return new RecvRespPackage(bytes[1], bytes[2]);
|
||||
|
Reference in New Issue
Block a user