diff --git a/server/src/Peripherals/CameraClient.cs b/server/src/Peripherals/CameraClient.cs index 519c34c..10cd399 100644 --- a/server/src/Peripherals/CameraClient.cs +++ b/server/src/Peripherals/CameraClient.cs @@ -214,7 +214,7 @@ class Camera public async ValueTask> ReadFrame() { // 只在第一次或出错时清除UDP缓冲区,避免每帧都清除造成延迟 - // await MsgBus.UDPServer.ClearUDPData(this.address, this.taskID); + MsgBus.UDPServer.ClearUDPData(this.address, this.taskID); logger.Trace($"Reading frame from camera {this.address}"); @@ -253,7 +253,7 @@ class Camera private async ValueTask> ReadRegister(UInt16 registerAddr) { var i2c = new Peripherals.I2cClient.I2c(this.address, this.port, this.taskID, this.timeout); - + // 地址高低字节 var addrBytes = new byte[2]; addrBytes[0] = (byte)(registerAddr >> 8); @@ -280,6 +280,8 @@ class Camera /// 配置结果 public async ValueTask> ConfigureRegisters(UInt16[][] registerTable, int? customDelayMs = null) { + MsgBus.UDPServer.ClearUDPData(this.address, this.taskID); + var i2c = new Peripherals.I2cClient.I2c(this.address, this.port, this.taskID, this.timeout); foreach (var cmd in registerTable) @@ -1302,20 +1304,20 @@ class Camera logger.Error($"读取自动对焦初始化状态失败: {readResult.Error}"); return new(readResult.Error); } - + logger.Trace($"自动对焦初始化状态检查, state=0x{readResult.Value:X2}"); - + if (readResult.Value == 0x70) { break; // 初始化完成 } - + if (iteration == 1) { logger.Error($"自动对焦初始化状态检查超时!! state=0x{readResult.Value:X2}"); return new(new Exception($"自动对焦初始化状态检查超时, state=0x{readResult.Value:X2}")); } - + await Task.Delay(1); } diff --git a/server/src/UdpServer.cs b/server/src/UdpServer.cs index 6e8eeca..a1f23ca 100644 --- a/server/src/UdpServer.cs +++ b/server/src/UdpServer.cs @@ -484,6 +484,151 @@ public class UDPServer // 清空队列的最有效方式是替换为新的队列 udpData.TryUpdate(key, new ConcurrentQueue(), dataQueue); } + + // 强制进行ARP刷新,防止后续传输时造成影响 + FlushArpEntry(ipAddr); + } + + /// + /// 跨平台ARP缓存刷新 + /// + /// 目标IP地址 + private void FlushArpEntry(string ipAddr) + { + try + { + // 验证IP地址格式 + if (!IPAddress.TryParse(ipAddr, out var _)) + { + logger.Warn($"Invalid IP address format: {ipAddr}"); + return; + } + + string command; + string arguments; + + if (OperatingSystem.IsWindows()) + { + // Windows: arp -d + command = "arp"; + arguments = $"-d {ipAddr}"; + } + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) + { + // Linux/macOS: ip neigh del dev (优先使用 ip 命令) + // 如果 ip 命令不可用,则使用 arp -d + if (IsCommandAvailable("ip")) + { + command = "ip"; + arguments = $"neigh flush {ipAddr}"; + } + else if (IsCommandAvailable("arp")) + { + command = "arp"; + arguments = $"-d {ipAddr}"; + } + else + { + logger.Warn("Neither 'ip' nor 'arp' command is available for ARP cache flush"); + return; + } + } + else + { + logger.Warn($"Unsupported operating system for ARP cache flush"); + return; + } + + // 异步执行命令,避免阻塞主线程 + Task.Run(() => ExecuteArpCommand(command, arguments, ipAddr)); + } + catch (Exception ex) + { + logger.Error($"Error during ARP cache flush for {ipAddr}: {ex.Message}"); + } + } + + /// + /// 检查系统命令是否可用 + /// + /// 命令名称 + /// 命令是否可用 + private bool IsCommandAvailable(string command) + { + try + { + var process = new System.Diagnostics.Process + { + StartInfo = new System.Diagnostics.ProcessStartInfo + { + FileName = OperatingSystem.IsWindows() ? "where" : "which", + Arguments = command, + UseShellExecute = false, + RedirectStandardOutput = true, + CreateNoWindow = true + } + }; + + process.Start(); + process.WaitForExit(1000); // 1秒超时 + return process.ExitCode == 0; + } + catch + { + return false; + } + } + + /// + /// 执行ARP命令 + /// + /// 命令 + /// 参数 + /// IP地址 + private void ExecuteArpCommand(string command, string arguments, string ipAddr) + { + try + { + var process = new System.Diagnostics.Process + { + StartInfo = new System.Diagnostics.ProcessStartInfo + { + FileName = command, + Arguments = arguments, + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = true + } + }; + + process.Start(); + + // 设置超时时间,避免进程挂起 + if (process.WaitForExit(5000)) // 5秒超时 + { + var output = process.StandardOutput.ReadToEnd(); + var error = process.StandardError.ReadToEnd(); + + if (process.ExitCode == 0) + { + logger.Debug($"ARP cache flush successful for {ipAddr}"); + } + else + { + logger.Warn($"ARP cache flush failed for {ipAddr}. Exit code: {process.ExitCode}, Error: {error}"); + } + } + else + { + process.Kill(); + logger.Warn($"ARP cache flush command timed out for {ipAddr}"); + } + } + catch (Exception ex) + { + logger.Error($"Failed to execute ARP cache flush command for {ipAddr}: {ex.Message}"); + } } ///