add test solution and try to fix get id code bug
This commit is contained in:
parent
5e2da17c28
commit
e8ec4c2a86
|
@ -10,3 +10,7 @@ publish: _show-dir
|
||||||
[working-directory: "server"]
|
[working-directory: "server"]
|
||||||
run-server: _show-dir
|
run-server: _show-dir
|
||||||
dotnet run
|
dotnet run
|
||||||
|
|
||||||
|
[working-directory: "server.test"]
|
||||||
|
test-server: _show-dir
|
||||||
|
dotnet test
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
bin
|
||||||
|
obj
|
|
@ -0,0 +1,36 @@
|
||||||
|
namespace server.test.UDPServer;
|
||||||
|
|
||||||
|
public class UnitTest1
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void UDPDataDeepClone()
|
||||||
|
{
|
||||||
|
var udpData = new UDPData()
|
||||||
|
{
|
||||||
|
DateTime = DateTime.Now,
|
||||||
|
Address = "127.0.0.1",
|
||||||
|
Port = 1234,
|
||||||
|
Data = new byte[] { 0xf0, 00, 00, 00 },
|
||||||
|
HasRead = false
|
||||||
|
};
|
||||||
|
var cloneUdpData = udpData.DeepClone();
|
||||||
|
|
||||||
|
Assert.Equal(udpData.DateTime, cloneUdpData.DateTime);
|
||||||
|
Assert.Equal(udpData.Address, cloneUdpData.Address);
|
||||||
|
Assert.Equal(udpData.Port, cloneUdpData.Port);
|
||||||
|
Assert.Equal(udpData.Data, cloneUdpData.Data);
|
||||||
|
Assert.Equal(udpData.HasRead, cloneUdpData.HasRead);
|
||||||
|
|
||||||
|
udpData.DateTime = DateTime.Now;
|
||||||
|
udpData.Address = "192.168.1.1";
|
||||||
|
udpData.Port = 33000;
|
||||||
|
udpData.Data = new byte[] { 0x0f, 00, 00, 00 };
|
||||||
|
udpData.HasRead = true;
|
||||||
|
|
||||||
|
Assert.NotEqual(udpData.DateTime, cloneUdpData.DateTime);
|
||||||
|
Assert.NotEqual(udpData.Address, cloneUdpData.Address);
|
||||||
|
Assert.NotEqual(udpData.Port, cloneUdpData.Port);
|
||||||
|
Assert.NotEqual(udpData.Data, cloneUdpData.Data);
|
||||||
|
Assert.NotEqual(udpData.HasRead, cloneUdpData.HasRead);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="coverlet.collector" Version="6.0.2" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.4" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
|
||||||
|
<PackageReference Include="xunit" Version="2.9.2" />
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Using Include="Xunit" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\server\server.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -79,8 +79,6 @@ try
|
||||||
|
|
||||||
// Setup Program
|
// Setup Program
|
||||||
MsgBus.Init();
|
MsgBus.Init();
|
||||||
// if (app.Environment.IsDevelopment()) MsgBus.UDPServer.EnableDebugMode = true;
|
|
||||||
MsgBus.UDPServer.EnableDebugMode = true;
|
|
||||||
|
|
||||||
// Router
|
// Router
|
||||||
// API Get
|
// API Get
|
||||||
|
|
|
@ -60,6 +60,11 @@
|
||||||
"finalMinLevel": "Info",
|
"finalMinLevel": "Info",
|
||||||
"writeTo": "Console"
|
"writeTo": "Console"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"logger": "server",
|
||||||
|
"finalMinLevel": "Trace",
|
||||||
|
"writeTo": "EachFile"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"logger": "server.*",
|
"logger": "server.*",
|
||||||
"finalMinLevel": "Trace",
|
"finalMinLevel": "Trace",
|
||||||
|
|
|
@ -50,14 +50,14 @@ namespace Common
|
||||||
{
|
{
|
||||||
for (var i = 0; i < len; i++)
|
for (var i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
num += Convert.ToUInt64(bytes[len - 1 - i] << (i << 3));
|
num += Convert.ToUInt64((UInt64)bytes[len - 1 - i] << (i << 3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (var i = 0; i < len; i++)
|
for (var i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
num += Convert.ToUInt64(bytes[i] << ((int)(len - 1 - i) << 3));
|
num += Convert.ToUInt64((UInt64)bytes[i] << ((int)(len - 1 - i) << 3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -245,7 +245,7 @@ class Jtag
|
||||||
ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
|
ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
|
||||||
if (!ret) throw new Exception("Send Address Package Failed!");
|
if (!ret) throw new Exception("Send Address Package Failed!");
|
||||||
|
|
||||||
// Wait for Ack
|
// Wait for Read Ack
|
||||||
if (!MsgBus.IsRunning)
|
if (!MsgBus.IsRunning)
|
||||||
throw new Exception("Message Bus not Working!");
|
throw new Exception("Message Bus not Working!");
|
||||||
|
|
||||||
|
@ -261,7 +261,7 @@ class Jtag
|
||||||
if (retPackLen != 4)
|
if (retPackLen != 4)
|
||||||
throw new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes");
|
throw new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes");
|
||||||
|
|
||||||
return (uint)(NumberProcessor.BytesToNumber(retPackOpts.Data));
|
return Convert.ToUInt32(NumberProcessor.BytesToNumber(retPackOpts.Data).Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async ValueTask<Result<RecvDataPackage>> RunCommand(uint devAddr, uint command)
|
public async ValueTask<Result<RecvDataPackage>> RunCommand(uint devAddr, uint command)
|
||||||
|
@ -279,6 +279,11 @@ class Jtag
|
||||||
opts.IsWrite = true;
|
opts.IsWrite = true;
|
||||||
ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
|
ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
|
||||||
if (!ret) throw new Exception("Send 1st address package failed!");
|
if (!ret) throw new Exception("Send 1st address package failed!");
|
||||||
|
// Send Data Package
|
||||||
|
ret = await UDPClientPool.SendDataPackAsync(ep,
|
||||||
|
new SendDataPackage(NumberProcessor.NumberToBytes(command, 4).Value));
|
||||||
|
if (!ret) throw new Exception("Send data package failed!");
|
||||||
|
|
||||||
// Check Msg Bus
|
// Check Msg Bus
|
||||||
if (!MsgBus.IsRunning)
|
if (!MsgBus.IsRunning)
|
||||||
throw new Exception("Message bus not working!");
|
throw new Exception("Message bus not working!");
|
||||||
|
@ -288,10 +293,6 @@ class Jtag
|
||||||
if (!udpResp.IsSuccessful || !udpResp.Value.IsSuccessful)
|
if (!udpResp.IsSuccessful || !udpResp.Value.IsSuccessful)
|
||||||
throw new Exception("Send address package failed");
|
throw new Exception("Send address package failed");
|
||||||
}
|
}
|
||||||
// Send Data Package
|
|
||||||
ret = await UDPClientPool.SendDataPackAsync(ep,
|
|
||||||
new SendDataPackage(NumberProcessor.NumberToBytes(command, 4).Value));
|
|
||||||
if (!ret) throw new Exception("Send data package failed!");
|
|
||||||
|
|
||||||
// Read Jtag State Register
|
// Read Jtag State Register
|
||||||
opts.IsWrite = false;
|
opts.IsWrite = false;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using DotNext;
|
using DotNext;
|
||||||
using DotNext.Threading;
|
using DotNext.Threading;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
@ -30,6 +30,24 @@ public class UDPData
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public required bool HasRead { get; set; }
|
public required bool HasRead { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 深度拷贝对象
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>UDPData</returns>
|
||||||
|
public UDPData DeepClone()
|
||||||
|
{
|
||||||
|
var cloneData = new byte[this.Data.Length];
|
||||||
|
Buffer.BlockCopy(this.Data, 0, cloneData, 0, this.Data.Length);
|
||||||
|
return new UDPData()
|
||||||
|
{
|
||||||
|
DateTime = this.DateTime,
|
||||||
|
Address = new string(this.Address),
|
||||||
|
Port = this.Port,
|
||||||
|
Data = cloneData,
|
||||||
|
HasRead = this.HasRead
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 将UDP Data 转化为Json 格式字符串
|
/// 将UDP Data 转化为Json 格式字符串
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -56,11 +74,6 @@ public class UDPServer
|
||||||
private Dictionary<string, List<UDPData>> udpData = new Dictionary<string, List<UDPData>>();
|
private Dictionary<string, List<UDPData>> udpData = new Dictionary<string, List<UDPData>>();
|
||||||
private AsyncReaderWriterLock udpDataLock = new AsyncReaderWriterLock(1);
|
private AsyncReaderWriterLock udpDataLock = new AsyncReaderWriterLock(1);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否开启Debug模式
|
|
||||||
/// </summary>
|
|
||||||
public bool EnableDebugMode { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Construct a udp server with fixed port
|
/// Construct a udp server with fixed port
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -90,11 +103,18 @@ public class UDPServer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ipAddr"> IP Address</param>
|
/// <param name="ipAddr"> IP Address</param>
|
||||||
/// <param name="timeout"> Read and Write Wait for Milliseconds </param>
|
/// <param name="timeout"> Read and Write Wait for Milliseconds </param>
|
||||||
|
/// <param name="callerName">调用函数名称</param>
|
||||||
|
/// <param name="callerLineNum">调用函数位置</param>
|
||||||
/// <returns>UDP Data</returns>
|
/// <returns>UDP Data</returns>
|
||||||
public Optional<UDPData> FindData(string ipAddr, int timeout = 1000)
|
public Optional<UDPData> FindData(
|
||||||
|
string ipAddr, int timeout = 1000,
|
||||||
|
[CallerMemberName] string callerName = "",
|
||||||
|
[CallerLineNumber] int callerLineNum = 0)
|
||||||
{
|
{
|
||||||
UDPData? data = null;
|
UDPData? data = null;
|
||||||
|
|
||||||
|
logger.Debug($"Caller \"{callerName}|{callerLineNum}\": Try to find {ipAddr} UDP Data");
|
||||||
|
|
||||||
var startTime = DateTime.Now;
|
var startTime = DateTime.Now;
|
||||||
var isTimeout = false;
|
var isTimeout = false;
|
||||||
var timeleft = TimeSpan.FromMilliseconds(timeout);
|
var timeleft = TimeSpan.FromMilliseconds(timeout);
|
||||||
|
@ -105,7 +125,7 @@ public class UDPServer
|
||||||
{
|
{
|
||||||
if (udpData.ContainsKey(ipAddr) && udpData[ipAddr].Count > 0)
|
if (udpData.ContainsKey(ipAddr) && udpData[ipAddr].Count > 0)
|
||||||
{
|
{
|
||||||
data = udpData[ipAddr][0];
|
data = udpData[ipAddr][0].DeepClone();
|
||||||
udpData[ipAddr].RemoveAt(0);
|
udpData[ipAddr].RemoveAt(0);
|
||||||
logger.Debug($"Find UDP Data: {data.ToString()}");
|
logger.Debug($"Find UDP Data: {data.ToString()}");
|
||||||
break;
|
break;
|
||||||
|
@ -132,15 +152,22 @@ public class UDPServer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ipAddr"> 目标IP地址 </param>
|
/// <param name="ipAddr"> 目标IP地址 </param>
|
||||||
/// <param name="timeout">超时时间</param>
|
/// <param name="timeout">超时时间</param>
|
||||||
|
/// <param name="callerName">调用函数名称</param>
|
||||||
|
/// <param name="callerLineNum">调用函数位置</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// 异步Optional 数据包:
|
/// 异步Optional 数据包:
|
||||||
/// Optional 为空时,表明找不到数据;
|
/// Optional 为空时,表明找不到数据;
|
||||||
/// Optional 存在时,为最先收到的数据
|
/// Optional 存在时,为最先收到的数据
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public async ValueTask<Optional<UDPData>> FindDataAsync(string ipAddr, int timeout = 1000)
|
public async ValueTask<Optional<UDPData>> FindDataAsync(
|
||||||
|
string ipAddr, int timeout = 1000,
|
||||||
|
[CallerMemberName] string callerName = "",
|
||||||
|
[CallerLineNumber] int callerLineNum = 0)
|
||||||
{
|
{
|
||||||
UDPData? data = null;
|
UDPData? data = null;
|
||||||
|
|
||||||
|
logger.Debug($"Caller \"{callerName}|{callerLineNum}\": Try to find {ipAddr} UDP Data");
|
||||||
|
|
||||||
var startTime = DateTime.Now;
|
var startTime = DateTime.Now;
|
||||||
var isTimeout = false;
|
var isTimeout = false;
|
||||||
var timeleft = TimeSpan.FromMilliseconds(timeout);
|
var timeleft = TimeSpan.FromMilliseconds(timeout);
|
||||||
|
@ -151,7 +178,7 @@ public class UDPServer
|
||||||
{
|
{
|
||||||
if (udpData.ContainsKey(ipAddr) && udpData[ipAddr].Count > 0)
|
if (udpData.ContainsKey(ipAddr) && udpData[ipAddr].Count > 0)
|
||||||
{
|
{
|
||||||
data = udpData[ipAddr][0];
|
data = udpData[ipAddr][0].DeepClone();
|
||||||
udpData[ipAddr].RemoveAt(0);
|
udpData[ipAddr].RemoveAt(0);
|
||||||
logger.Debug($"Find UDP Data: {data.ToString()}");
|
logger.Debug($"Find UDP Data: {data.ToString()}");
|
||||||
break;
|
break;
|
||||||
|
@ -215,7 +242,7 @@ public class UDPServer
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异步等待读响应或写响应
|
/// 异步等待写响应
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="address">IP地址</param>
|
/// <param name="address">IP地址</param>
|
||||||
/// <param name="port">UDP 端口</param>
|
/// <param name="port">UDP 端口</param>
|
||||||
|
@ -266,6 +293,7 @@ public class UDPServer
|
||||||
|
|
||||||
private void ReceiveHandler(IAsyncResult res)
|
private void ReceiveHandler(IAsyncResult res)
|
||||||
{
|
{
|
||||||
|
logger.Trace("Enter handler");
|
||||||
var remoteEP = new IPEndPoint(IPAddress.Any, listenPort);
|
var remoteEP = new IPEndPoint(IPAddress.Any, listenPort);
|
||||||
byte[] bytes = listener.EndReceive(res, ref remoteEP);
|
byte[] bytes = listener.EndReceive(res, ref remoteEP);
|
||||||
|
|
||||||
|
@ -278,67 +306,13 @@ public class UDPServer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// If enable Debug mode, exec Debug handler
|
|
||||||
if (EnableDebugMode)
|
|
||||||
{
|
|
||||||
DebugHandler(new IPEndPoint(IPAddress.Parse("127.0.0.1"), this.listenPort), bytes);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Handle Package
|
// Handle Package
|
||||||
PrintData(RecordUDPData(bytes, remoteEP));
|
PrintData(RecordUDPData(bytes, remoteEP));
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_RECEIVE:
|
BEGIN_RECEIVE:
|
||||||
listener.BeginReceive(new AsyncCallback(ReceiveHandler), null);
|
listener.BeginReceive(new AsyncCallback(ReceiveHandler), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DebugHandler(IPEndPoint ep, byte[] bytes)
|
|
||||||
{
|
|
||||||
// Print Receive Data
|
|
||||||
var data = new UDPData()
|
|
||||||
{
|
|
||||||
Address = ep.Address.ToString(),
|
|
||||||
Port = ep.Port,
|
|
||||||
Data = bytes,
|
|
||||||
DateTime = DateTime.Now,
|
|
||||||
HasRead = false,
|
|
||||||
};
|
|
||||||
PrintData(data);
|
|
||||||
|
|
||||||
// Handle Pack Type
|
|
||||||
var sign = bytes[0];
|
|
||||||
if (sign == (byte)WebProtocol.PackSign.SendAddr)
|
|
||||||
{
|
|
||||||
var resData = WebProtocol.SendAddrPackage.FromBytes(bytes);
|
|
||||||
if (!resData.IsSuccessful)
|
|
||||||
{
|
|
||||||
logger.Warn("DebugHandler: Convert to SendAddrPackage failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resData.Value.Options.IsWrite)
|
|
||||||
{
|
|
||||||
var pack = new WebProtocol.RecvRespPackage(resData.Value.Options.CommandID, true);
|
|
||||||
SendBytes(ep, pack.ToBytes());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var pack = new WebProtocol.RecvDataPackage(resData.Value.Options.CommandID, true, [0, 0, 0, 0]);
|
|
||||||
SendBytes(ep, pack.ToBytes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (sign == (byte)WebProtocol.PackSign.SendData)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SendString(ep, "DebugHandler: Receive Data");
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Trace("DebugHandler: send pack successfully");
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool SendBytes(IPEndPoint endPoint, byte[] buf)
|
private bool SendBytes(IPEndPoint endPoint, byte[] buf)
|
||||||
{
|
{
|
||||||
var sendLen = listener.Send(buf, endPoint);
|
var sendLen = listener.Send(buf, endPoint);
|
||||||
|
@ -380,7 +354,9 @@ public class UDPServer
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
udpData.Add(remoteAddress, new List<UDPData>([data]));
|
var list = new List<UDPData>();
|
||||||
|
list.Add(data);
|
||||||
|
udpData.Add(remoteAddress, list);
|
||||||
logger.Trace("Receive data from new client");
|
logger.Trace("Receive data from new client");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -478,7 +478,7 @@ namespace WebProtocol
|
||||||
{
|
{
|
||||||
if (bytes[0] != (byte)PackSign.RecvResp)
|
if (bytes[0] != (byte)PackSign.RecvResp)
|
||||||
throw new ArgumentException(
|
throw new ArgumentException(
|
||||||
"The sign of bytes is not RecvData Package!",
|
"The sign of bytes is not RecvResp Package!",
|
||||||
nameof(bytes)
|
nameof(bytes)
|
||||||
);
|
);
|
||||||
return new RecvRespPackage(bytes[1], bytes[2]);
|
return new RecvRespPackage(bytes[1], bytes[2]);
|
||||||
|
|
Loading…
Reference in New Issue