diff --git a/server/src/ArpClient.cs b/server/src/ArpClient.cs
index 4172ac9..3d35969 100644
--- a/server/src/ArpClient.cs
+++ b/server/src/ArpClient.cs
@@ -82,7 +82,9 @@ public static class Arp
try
{
- string command = GetArpAddCommand(ipAddress, macAddress, interfaceName);
+ // 格式化 MAC 地址以适配不同操作系统
+ string formattedMac = FormatMacAddress(macAddress);
+ string command = GetArpAddCommand(ipAddress, formattedMac, interfaceName);
var result = await ExecuteCommandAsync(command);
return result.IsSuccess;
}
@@ -359,8 +361,19 @@ public static class Arp
///
private static ArpEntry? ParseWindowsArpEntry(string line)
{
+ // 跳过空行和标题行
+ if (string.IsNullOrWhiteSpace(line) ||
+ line.Contains("Interface:") ||
+ line.Contains("Internet Address") ||
+ line.Contains("Physical Address") ||
+ line.Contains("Type"))
+ {
+ return null;
+ }
+
// Windows arp -a 输出格式: IP地址 物理地址 类型
- var pattern = @"(\d+\.\d+\.\d+\.\d+)\s+([a-fA-F0-9-]{17})\s+(\w+)";
+ // 示例: 172.6.0.1 e4-3a-6e-29-c3-5b dynamic
+ var pattern = @"^\s*(\d+\.\d+\.\d+\.\d+)\s+([a-fA-F0-9-]{17})\s+(\w+)\s*$";
var match = Regex.Match(line, pattern);
if (match.Success)
@@ -368,7 +381,7 @@ public static class Arp
return new ArpEntry
{
IpAddress = match.Groups[1].Value,
- MacAddress = match.Groups[2].Value.Replace('-', ':'),
+ MacAddress = FormatMacAddress(match.Groups[2].Value), // 格式化 MAC 地址
Type = match.Groups[3].Value
};
}
@@ -391,7 +404,7 @@ public static class Arp
{
Hostname = match.Groups[1].Value,
IpAddress = match.Groups[2].Value,
- MacAddress = match.Groups[3].Value,
+ MacAddress = FormatMacAddress(match.Groups[3].Value), // 格式化 MAC 地址
Type = match.Groups[5].Value,
Interface = match.Groups[6].Value
};
@@ -406,7 +419,7 @@ public static class Arp
return new ArpEntry
{
IpAddress = simpleMatch.Groups[1].Value,
- MacAddress = simpleMatch.Groups[2].Value,
+ MacAddress = FormatMacAddress(simpleMatch.Groups[2].Value), // 格式化 MAC 地址
Interface = simpleMatch.Groups[3].Value
};
}
@@ -448,8 +461,11 @@ public static class Arp
if (string.IsNullOrWhiteSpace(macAddress))
throw new ArgumentException("MAC 地址不能为空", nameof(macAddress));
+ // 格式化 MAC 地址以适配不同操作系统
+ string formattedMac = FormatMacAddress(macAddress);
+
var entry = await GetArpEntryAsync(ipAddress);
- if (entry != null && string.Equals(entry.MacAddress, macAddress, StringComparison.OrdinalIgnoreCase))
+ if (entry != null && string.Equals(FormatMacAddress(entry.MacAddress), formattedMac, StringComparison.OrdinalIgnoreCase))
{
// 已存在且 MAC 匹配,无需操作
return true;
@@ -462,7 +478,33 @@ public static class Arp
}
// 新增 ARP 记录
- return await AddArpEntryAsync(ipAddress, macAddress, interfaceName);
+ return await AddArpEntryAsync(ipAddress, formattedMac, interfaceName);
+ }
+
+ ///
+ /// 格式化 MAC 地址为指定平台格式
+ ///
+ /// 原始 MAC 地址
+ /// 格式化后的 MAC 地址
+ public static string FormatMacAddress(string macAddress)
+ {
+ if (string.IsNullOrWhiteSpace(macAddress))
+ return string.Empty;
+
+ var cleaned = macAddress.Replace("-", "").Replace(":", "").ToLowerInvariant();
+ if (cleaned.Length != 12)
+ return macAddress;
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ // Windows: XX-XX-XX-XX-XX-XX
+ return string.Join("-", Enumerable.Range(0, 6).Select(i => cleaned.Substring(i * 2, 2)));
+ }
+ else
+ {
+ // Unix/Linux/macOS: xx:xx:xx:xx:xx:xx
+ return string.Join(":", Enumerable.Range(0, 6).Select(i => cleaned.Substring(i * 2, 2)));
+ }
}
}
///
diff --git a/server/src/Controllers/NetConfigController.cs b/server/src/Controllers/NetConfigController.cs
index e62313a..3adda80 100644
--- a/server/src/Controllers/NetConfigController.cs
+++ b/server/src/Controllers/NetConfigController.cs
@@ -16,9 +16,167 @@ public class NetConfigController : ControllerBase
{
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
- // 固定的实验板IP和端口
+ // 固定的实验板IP,端口,MAC地址
private const string BOARD_IP = "169.254.109.0";
private const int BOARD_PORT = 1234;
+ private const string BOARD_MAC = "12:34:56:78:9a:bc";
+
+ // 本机网络信息
+ private readonly IPAddress _localIP;
+ private readonly byte[] _localMAC;
+ private readonly string _localIPString;
+ private readonly string _localMACString;
+ private readonly string _localInterface;
+
+ public NetConfigController()
+ {
+ // 初始化本机IP地址
+ _localIP = GetLocalIPAddress();
+ _localIPString = _localIP?.ToString() ?? "未知";
+
+ // 初始化本机MAC地址
+ _localMAC = GetLocalMACAddress();
+ _localMACString = _localMAC != null ? BitConverter.ToString(_localMAC).Replace("-", ":") : "未知";
+
+ // 获取本机网络接口名称
+ _localInterface = GetLocalNetworkInterface();
+
+ logger.Info($"NetConfigController 初始化完成 - 本机IP: {_localIPString}, 本机MAC: {_localMACString}, 接口: {_localInterface}");
+ }
+
+ ///
+ /// 获取本机IP地址(优先选择与实验板同网段的IP)
+ ///
+ /// 本机IP地址
+ private IPAddress GetLocalIPAddress()
+ {
+ try
+ {
+ var boardIpSegments = BOARD_IP.Split('.').Take(3).ToArray();
+
+ // 优先选择与实验板IP前三段相同的IP
+ var sameSegmentIP = System.Net.NetworkInformation.NetworkInterface
+ .GetAllNetworkInterfaces()
+ .Where(nic => nic.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up
+ && nic.NetworkInterfaceType != System.Net.NetworkInformation.NetworkInterfaceType.Loopback)
+ .SelectMany(nic => nic.GetIPProperties().UnicastAddresses)
+ .Where(addr => addr.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
+ .Select(addr => addr.Address)
+ .FirstOrDefault(addr =>
+ {
+ var segments = addr.ToString().Split('.');
+ return segments.Length == 4 &&
+ segments[0] == boardIpSegments[0] &&
+ segments[1] == boardIpSegments[1] &&
+ segments[2] == boardIpSegments[2];
+ });
+
+ if (sameSegmentIP != null)
+ return sameSegmentIP;
+
+ // 如果没有找到同网段的IP,返回第一个可用的IP
+ return System.Net.NetworkInformation.NetworkInterface
+ .GetAllNetworkInterfaces()
+ .Where(nic => nic.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up
+ && nic.NetworkInterfaceType != System.Net.NetworkInformation.NetworkInterfaceType.Loopback)
+ .SelectMany(nic => nic.GetIPProperties().UnicastAddresses)
+ .Where(addr => addr.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
+ .Select(addr => addr.Address)
+ .FirstOrDefault() ?? IPAddress.Loopback;
+ }
+ catch (Exception ex)
+ {
+ logger.Error(ex, "获取本机IP地址失败");
+ return IPAddress.Loopback;
+ }
+ }
+
+ ///
+ /// 获取本机MAC地址
+ ///
+ /// 本机MAC地址字节数组
+ private byte[] GetLocalMACAddress()
+ {
+ try
+ {
+ return System.Net.NetworkInformation.NetworkInterface
+ .GetAllNetworkInterfaces()
+ .Where(nic => nic.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up
+ && nic.NetworkInterfaceType != System.Net.NetworkInformation.NetworkInterfaceType.Loopback)
+ .Select(nic => nic.GetPhysicalAddress()?.GetAddressBytes())
+ .FirstOrDefault(bytes => bytes != null && bytes.Length == 6) ?? new byte[6];
+ }
+ catch (Exception ex)
+ {
+ logger.Error(ex, "获取本机MAC地址失败");
+ return new byte[6];
+ }
+ }
+
+ ///
+ /// 获取本机网络接口名称
+ ///
+ /// 网络接口名称
+ private string GetLocalNetworkInterface()
+ {
+ try
+ {
+ var boardIpSegments = BOARD_IP.Split('.').Take(3).ToArray();
+
+ // 优先选择与实验板IP前三段相同的网络接口
+ var sameSegmentInterface = System.Net.NetworkInformation.NetworkInterface
+ .GetAllNetworkInterfaces()
+ .Where(nic => nic.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up
+ && nic.NetworkInterfaceType != System.Net.NetworkInformation.NetworkInterfaceType.Loopback)
+ .FirstOrDefault(nic =>
+ {
+ var ipAddresses = nic.GetIPProperties().UnicastAddresses
+ .Where(addr => addr.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
+ .Select(addr => addr.Address);
+
+ return ipAddresses.Any(addr =>
+ {
+ var segments = addr.ToString().Split('.');
+ return segments.Length == 4 &&
+ segments[0] == boardIpSegments[0] &&
+ segments[1] == boardIpSegments[1] &&
+ segments[2] == boardIpSegments[2];
+ });
+ });
+
+ if (sameSegmentInterface != null)
+ return sameSegmentInterface.Name;
+
+ // 如果没有找到同网段的接口,返回第一个可用的接口
+ return System.Net.NetworkInformation.NetworkInterface
+ .GetAllNetworkInterfaces()
+ .Where(nic => nic.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up
+ && nic.NetworkInterfaceType != System.Net.NetworkInformation.NetworkInterfaceType.Loopback)
+ .FirstOrDefault()?.Name ?? "未知";
+ }
+ catch (Exception ex)
+ {
+ logger.Error(ex, "获取本机网络接口名称失败");
+ return "未知";
+ }
+ }
+
+ ///
+ /// 初始化ARP记录
+ ///
+ /// 是否成功
+ private async Task InitializeArpAsync()
+ {
+ try
+ {
+ return await Arp.CheckOrAddAsync(BOARD_IP, BOARD_MAC, _localInterface);
+ }
+ catch (Exception ex)
+ {
+ logger.Error(ex, "初始化ARP记录失败");
+ return false;
+ }
+ }
///
/// 获取主机IP地址
@@ -32,11 +190,12 @@ public class NetConfigController : ControllerBase
{
try
{
- var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
- if (!(await netConfig.Init()))
+ if (!(await InitializeArpAsync()))
{
- throw new Exception($"无法配置ARP");
+ throw new Exception("无法配置ARP记录");
}
+
+ var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
var result = await netConfig.GetHostIP();
if (!result.IsSuccessful)
@@ -66,11 +225,12 @@ public class NetConfigController : ControllerBase
{
try
{
- var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
- if (!(await netConfig.Init()))
+ if (!(await InitializeArpAsync()))
{
- throw new Exception($"无法配置ARP");
+ throw new Exception("无法配置ARP记录");
}
+
+ var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
var result = await netConfig.GetBoardIP();
if (!result.IsSuccessful)
@@ -100,11 +260,12 @@ public class NetConfigController : ControllerBase
{
try
{
- var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
- if (!(await netConfig.Init()))
+ if (!(await InitializeArpAsync()))
{
- throw new Exception($"无法配置ARP");
+ throw new Exception("无法配置ARP记录");
}
+
+ var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
var result = await netConfig.GetHostMAC();
if (!result.IsSuccessful)
@@ -134,11 +295,12 @@ public class NetConfigController : ControllerBase
{
try
{
- var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
- if (!(await netConfig.Init()))
+ if (!(await InitializeArpAsync()))
{
- throw new Exception($"无法配置ARP");
+ throw new Exception("无法配置ARP记录");
}
+
+ var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
var result = await netConfig.GetBoardMAC();
if (!result.IsSuccessful)
@@ -168,12 +330,13 @@ public class NetConfigController : ControllerBase
{
try
{
- var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
- if (!(await netConfig.Init()))
+ if (!(await InitializeArpAsync()))
{
- throw new Exception($"无法配置ARP");
+ throw new Exception("无法配置ARP记录");
}
+ var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
+
var hostIPResult = await netConfig.GetHostIP();
var boardIPResult = await netConfig.GetBoardIP();
var hostMACResult = await netConfig.GetHostMAC();
@@ -255,12 +418,12 @@ public class NetConfigController : ControllerBase
try
{
- // 创建网络配置客户端
- var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
- if (!(await netConfig.Init()))
+ if (!(await InitializeArpAsync()))
{
- throw new Exception($"无法配置ARP");
+ throw new Exception("无法配置ARP记录");
}
+
+ var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
var result = await netConfig.SetHostIP(hostIpAddress);
if (!result.IsSuccessful)
@@ -298,12 +461,12 @@ public class NetConfigController : ControllerBase
try
{
- // 创建网络配置客户端
- var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
- if (!(await netConfig.Init()))
+ if (!(await InitializeArpAsync()))
{
- throw new Exception($"无法配置ARP");
+ throw new Exception("无法配置ARP记录");
}
+
+ var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
var result = await netConfig.SetBoardIP(newIpAddress);
if (!result.IsSuccessful)
@@ -342,12 +505,12 @@ public class NetConfigController : ControllerBase
try
{
- // 创建网络配置客户端
- var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
- if (!(await netConfig.Init()))
+ if (!(await InitializeArpAsync()))
{
- throw new Exception($"无法配置ARP");
+ throw new Exception("无法配置ARP记录");
}
+
+ var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
var result = await netConfig.SetHostMAC(macBytes);
if (!result.IsSuccessful)
@@ -377,33 +540,16 @@ public class NetConfigController : ControllerBase
{
try
{
- // 获取所有本机IPv4地址,并选择与实验板IP前三段相同的IP
- var boardIpSegments = BOARD_IP.Split('.').Take(3).ToArray();
- var ip = System.Net.NetworkInformation.NetworkInterface
- .GetAllNetworkInterfaces()
- .Where(nic => nic.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up
- && nic.NetworkInterfaceType != System.Net.NetworkInformation.NetworkInterfaceType.Loopback)
- .SelectMany(nic => nic.GetIPProperties().UnicastAddresses)
- .Where(addr => addr.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
- .Select(addr => addr.Address)
- .FirstOrDefault(addr =>
- {
- var segments = addr.ToString().Split('.');
- return segments.Length == 4 &&
- segments[0] == boardIpSegments[0] &&
- segments[1] == boardIpSegments[1] &&
- segments[2] == boardIpSegments[2];
- });
-
- if (ip == null)
+ if (_localIP == null)
return StatusCode(StatusCodes.Status500InternalServerError, "无法获取本机IP地址");
- var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
- if (!(await netConfig.Init()))
+ if (!(await InitializeArpAsync()))
{
- throw new Exception($"无法配置ARP");
+ throw new Exception("无法配置ARP记录");
}
- var result = await netConfig.SetHostIP(ip);
+
+ var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
+ var result = await netConfig.SetHostIP(_localIP);
if (!result.IsSuccessful)
{
@@ -431,27 +577,18 @@ public class NetConfigController : ControllerBase
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task UpdateHostMAC()
{
- byte[]? macBytes = null;
try
{
- // 获取本机第一个可用的MAC地址
- macBytes = System.Net.NetworkInformation.NetworkInterface
- .GetAllNetworkInterfaces()
- .Where(nic => nic.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up
- && nic.NetworkInterfaceType != System.Net.NetworkInformation.NetworkInterfaceType.Loopback)
- .Select(nic => nic.GetPhysicalAddress()?.GetAddressBytes())
- .FirstOrDefault(bytes => bytes != null && bytes.Length == 6);
-
- if (macBytes == null)
+ if (_localMAC == null || _localMAC.Length != 6)
return StatusCode(StatusCodes.Status500InternalServerError, "无法获取本机MAC地址");
- // 创建网络配置客户端
- var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
- if (!(await netConfig.Init()))
+ if (!(await InitializeArpAsync()))
{
- throw new Exception($"无法配置ARP");
+ throw new Exception("无法配置ARP记录");
}
- var result = await netConfig.SetHostMAC(macBytes);
+
+ var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
+ var result = await netConfig.SetHostMAC(_localMAC);
if (!result.IsSuccessful)
{
@@ -469,47 +606,20 @@ public class NetConfigController : ControllerBase
}
///
- /// 设置板卡MAC地址
+ /// 获取本机网络信息
///
- /// 板卡MAC地址(格式:AA:BB:CC:DD:EE:FF)
- /// 操作结果
- [HttpPost("SetBoardMAC")]
+ /// 本机网络信息
+ [HttpGet("GetLocalNetworkInfo")]
[EnableCors("Users")]
- [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status400BadRequest)]
- [ProducesResponseType(StatusCodes.Status500InternalServerError)]
- public async Task SetBoardMAC(string boardMac)
+ [ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
+ public IActionResult GetLocalNetworkInfo()
{
- if (string.IsNullOrWhiteSpace(boardMac))
- return BadRequest("板卡MAC地址不能为空");
-
- // 解析MAC地址
- if (!TryParseMacAddress(boardMac, out var macBytes))
- return BadRequest("MAC地址格式不正确,请使用格式:AA:BB:CC:DD:EE:FF");
-
- try
+ return Ok(new
{
- // 创建网络配置客户端
- var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
- if (!(await netConfig.Init()))
- {
- throw new Exception($"无法配置ARP");
- }
- var result = await netConfig.SetBoardMAC(macBytes);
-
- if (!result.IsSuccessful)
- {
- logger.Error($"设置板卡MAC地址失败: {result.Error}");
- return StatusCode(StatusCodes.Status500InternalServerError, $"设置失败: {result.Error}");
- }
-
- return Ok(result.Value);
- }
- catch (Exception ex)
- {
- logger.Error(ex, "设置板卡MAC地址时发生异常");
- return StatusCode(StatusCodes.Status500InternalServerError, "设置失败,请稍后重试");
- }
+ LocalIP = _localIPString,
+ LocalMAC = _localMACString,
+ LocalInterface = _localInterface
+ });
}
///
diff --git a/server/src/Peripherals/NetConfigClient.cs b/server/src/Peripherals/NetConfigClient.cs
index 9115a68..b90c200 100644
--- a/server/src/Peripherals/NetConfigClient.cs
+++ b/server/src/Peripherals/NetConfigClient.cs
@@ -26,8 +26,6 @@ public class NetConfig
readonly string address;
private IPEndPoint ep;
- const string DEFAULT_BOARD_MAC = "12:34:56:78:9a:bc";
-
///
/// Initialize NetConfig client
///
@@ -46,15 +44,6 @@ public class NetConfig
this.timeout = timeout;
}
- ///
- /// [TODO:description]
- ///
- /// [TODO:return]
- public async ValueTask Init()
- {
- return await Arp.CheckOrAddAsync(this.address, DEFAULT_BOARD_MAC);
- }
-
///
/// Set host IP address
///