From e8ec4c2a86d58fccc7b647a8e9481821cd24910a Mon Sep 17 00:00:00 2001 From: SikongJueluo Date: Tue, 15 Apr 2025 20:09:34 +0800 Subject: [PATCH] add test solution and try to fix get id code bug --- .justfile | 4 ++ server.test/.gitignore | 2 + server.test/UDPServerTest.cs | 36 +++++++++++ server.test/server.test.csproj | 26 ++++++++ server/Program.cs | 2 - server/appsettings.json | 5 ++ server/src/Common.cs | 4 +- server/src/JtagController.cs | 13 ++-- server/src/UdpServer.cs | 112 +++++++++++++-------------------- server/src/WebProtocol.cs | 2 +- 10 files changed, 127 insertions(+), 79 deletions(-) create mode 100644 server.test/.gitignore create mode 100644 server.test/UDPServerTest.cs create mode 100644 server.test/server.test.csproj diff --git a/.justfile b/.justfile index 7df70f6..0770d72 100644 --- a/.justfile +++ b/.justfile @@ -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 diff --git a/server.test/.gitignore b/server.test/.gitignore new file mode 100644 index 0000000..1746e32 --- /dev/null +++ b/server.test/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/server.test/UDPServerTest.cs b/server.test/UDPServerTest.cs new file mode 100644 index 0000000..cc7a80e --- /dev/null +++ b/server.test/UDPServerTest.cs @@ -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); + } +} diff --git a/server.test/server.test.csproj b/server.test/server.test.csproj new file mode 100644 index 0000000..2bcffed --- /dev/null +++ b/server.test/server.test.csproj @@ -0,0 +1,26 @@ + + + + net9.0 + enable + enable + false + + + + + + + + + + + + + + + + + + + diff --git a/server/Program.cs b/server/Program.cs index 2ec0f48..80f8ebb 100644 --- a/server/Program.cs +++ b/server/Program.cs @@ -79,8 +79,6 @@ try // Setup Program MsgBus.Init(); - // if (app.Environment.IsDevelopment()) MsgBus.UDPServer.EnableDebugMode = true; - MsgBus.UDPServer.EnableDebugMode = true; // Router // API Get diff --git a/server/appsettings.json b/server/appsettings.json index d035e31..92aa20f 100644 --- a/server/appsettings.json +++ b/server/appsettings.json @@ -60,6 +60,11 @@ "finalMinLevel": "Info", "writeTo": "Console" }, + { + "logger": "server", + "finalMinLevel": "Trace", + "writeTo": "EachFile" + }, { "logger": "server.*", "finalMinLevel": "Trace", diff --git a/server/src/Common.cs b/server/src/Common.cs index 066c3af..4ba5513 100644 --- a/server/src/Common.cs +++ b/server/src/Common.cs @@ -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)); } } diff --git a/server/src/JtagController.cs b/server/src/JtagController.cs index 28d065e..2502824 100644 --- a/server/src/JtagController.cs +++ b/server/src/JtagController.cs @@ -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> 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; diff --git a/server/src/UdpServer.cs b/server/src/UdpServer.cs index 8489f3d..d3d480d 100644 --- a/server/src/UdpServer.cs +++ b/server/src/UdpServer.cs @@ -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 /// public required bool HasRead { get; set; } + /// + /// 深度拷贝对象 + /// + /// UDPData + 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 + }; + } + /// /// 将UDP Data 转化为Json 格式字符串 /// @@ -56,11 +74,6 @@ public class UDPServer private Dictionary> udpData = new Dictionary>(); private AsyncReaderWriterLock udpDataLock = new AsyncReaderWriterLock(1); - /// - /// 是否开启Debug模式 - /// - public bool EnableDebugMode { get; set; } - /// /// Construct a udp server with fixed port /// @@ -90,11 +103,18 @@ public class UDPServer /// /// IP Address /// Read and Write Wait for Milliseconds + /// 调用函数名称 + /// 调用函数位置 /// UDP Data - public Optional FindData(string ipAddr, int timeout = 1000) + public Optional 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 /// /// 目标IP地址 /// 超时时间 + /// 调用函数名称 + /// 调用函数位置 /// /// 异步Optional 数据包: /// Optional 为空时,表明找不到数据; /// Optional 存在时,为最先收到的数据 /// - public async ValueTask> FindDataAsync(string ipAddr, int timeout = 1000) + public async ValueTask> 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 } /// - /// 异步等待读响应或写响应 + /// 异步等待写响应 /// /// IP地址 /// UDP 端口 @@ -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)); - } + // 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([data])); + var list = new List(); + list.Add(data); + udpData.Add(remoteAddress, list); logger.Trace("Receive data from new client"); } diff --git a/server/src/WebProtocol.cs b/server/src/WebProtocol.cs index 8bce0fe..14c246e 100644 --- a/server/src/WebProtocol.cs +++ b/server/src/WebProtocol.cs @@ -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]);