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"]
|
||||
run-server: _show-dir
|
||||
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
|
||||
MsgBus.Init();
|
||||
// if (app.Environment.IsDevelopment()) MsgBus.UDPServer.EnableDebugMode = true;
|
||||
MsgBus.UDPServer.EnableDebugMode = true;
|
||||
|
||||
// Router
|
||||
// API Get
|
||||
|
|
|
@ -60,6 +60,11 @@
|
|||
"finalMinLevel": "Info",
|
||||
"writeTo": "Console"
|
||||
},
|
||||
{
|
||||
"logger": "server",
|
||||
"finalMinLevel": "Trace",
|
||||
"writeTo": "EachFile"
|
||||
},
|
||||
{
|
||||
"logger": "server.*",
|
||||
"finalMinLevel": "Trace",
|
||||
|
|
|
@ -50,14 +50,14 @@ namespace Common
|
|||
{
|
||||
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
|
||||
{
|
||||
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));
|
||||
if (!ret) throw new Exception("Send Address Package Failed!");
|
||||
|
||||
// Wait for Ack
|
||||
// Wait for Read Ack
|
||||
if (!MsgBus.IsRunning)
|
||||
throw new Exception("Message Bus not Working!");
|
||||
|
||||
|
@ -261,7 +261,7 @@ class Jtag
|
|||
if (retPackLen != 4)
|
||||
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)
|
||||
|
@ -279,6 +279,11 @@ class Jtag
|
|||
opts.IsWrite = true;
|
||||
ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
|
||||
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
|
||||
if (!MsgBus.IsRunning)
|
||||
throw new Exception("Message bus not working!");
|
||||
|
@ -288,10 +293,6 @@ class Jtag
|
|||
if (!udpResp.IsSuccessful || !udpResp.Value.IsSuccessful)
|
||||
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
|
||||
opts.IsWrite = false;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using DotNext;
|
||||
using DotNext.Threading;
|
||||
using Newtonsoft.Json;
|
||||
|
@ -30,6 +30,24 @@ public class UDPData
|
|||
/// </summary>
|
||||
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>
|
||||
/// 将UDP Data 转化为Json 格式字符串
|
||||
/// </summary>
|
||||
|
@ -56,11 +74,6 @@ public class UDPServer
|
|||
private Dictionary<string, List<UDPData>> udpData = new Dictionary<string, List<UDPData>>();
|
||||
private AsyncReaderWriterLock udpDataLock = new AsyncReaderWriterLock(1);
|
||||
|
||||
/// <summary>
|
||||
/// 是否开启Debug模式
|
||||
/// </summary>
|
||||
public bool EnableDebugMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Construct a udp server with fixed port
|
||||
/// </summary>
|
||||
|
@ -90,11 +103,18 @@ public class UDPServer
|
|||
/// </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)
|
||||
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);
|
||||
|
@ -105,7 +125,7 @@ public class UDPServer
|
|||
{
|
||||
if (udpData.ContainsKey(ipAddr) && udpData[ipAddr].Count > 0)
|
||||
{
|
||||
data = udpData[ipAddr][0];
|
||||
data = udpData[ipAddr][0].DeepClone();
|
||||
udpData[ipAddr].RemoveAt(0);
|
||||
logger.Debug($"Find UDP Data: {data.ToString()}");
|
||||
break;
|
||||
|
@ -132,15 +152,22 @@ public class UDPServer
|
|||
/// </summary>
|
||||
/// <param name="ipAddr"> 目标IP地址 </param>
|
||||
/// <param name="timeout">超时时间</param>
|
||||
/// <param name="callerName">调用函数名称</param>
|
||||
/// <param name="callerLineNum">调用函数位置</param>
|
||||
/// <returns>
|
||||
/// 异步Optional 数据包:
|
||||
/// Optional 为空时,表明找不到数据;
|
||||
/// Optional 存在时,为最先收到的数据
|
||||
/// </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;
|
||||
|
||||
logger.Debug($"Caller \"{callerName}|{callerLineNum}\": Try to find {ipAddr} UDP Data");
|
||||
|
||||
var startTime = DateTime.Now;
|
||||
var isTimeout = false;
|
||||
var timeleft = TimeSpan.FromMilliseconds(timeout);
|
||||
|
@ -151,7 +178,7 @@ public class UDPServer
|
|||
{
|
||||
if (udpData.ContainsKey(ipAddr) && udpData[ipAddr].Count > 0)
|
||||
{
|
||||
data = udpData[ipAddr][0];
|
||||
data = udpData[ipAddr][0].DeepClone();
|
||||
udpData[ipAddr].RemoveAt(0);
|
||||
logger.Debug($"Find UDP Data: {data.ToString()}");
|
||||
break;
|
||||
|
@ -215,7 +242,7 @@ public class UDPServer
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步等待读响应或写响应
|
||||
/// 异步等待写响应
|
||||
/// </summary>
|
||||
/// <param name="address">IP地址</param>
|
||||
/// <param name="port">UDP 端口</param>
|
||||
|
@ -266,6 +293,7 @@ public class UDPServer
|
|||
|
||||
private void ReceiveHandler(IAsyncResult res)
|
||||
{
|
||||
logger.Trace("Enter handler");
|
||||
var remoteEP = new IPEndPoint(IPAddress.Any, listenPort);
|
||||
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
|
||||
PrintData(RecordUDPData(bytes, remoteEP));
|
||||
}
|
||||
|
||||
BEGIN_RECEIVE:
|
||||
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)
|
||||
{
|
||||
var sendLen = listener.Send(buf, endPoint);
|
||||
|
@ -380,7 +354,9 @@ public class UDPServer
|
|||
}
|
||||
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");
|
||||
}
|
||||
|
||||
|
|
|
@ -478,7 +478,7 @@ namespace WebProtocol
|
|||
{
|
||||
if (bytes[0] != (byte)PackSign.RecvResp)
|
||||
throw new ArgumentException(
|
||||
"The sign of bytes is not RecvData Package!",
|
||||
"The sign of bytes is not RecvResp Package!",
|
||||
nameof(bytes)
|
||||
);
|
||||
return new RecvRespPackage(bytes[1], bytes[2]);
|
||||
|
|
Loading…
Reference in New Issue