fix: 修复arp在windows下无法正常配置的问题

This commit is contained in:
2025-07-18 13:51:23 +08:00
parent 9af2d3e87e
commit 35bad4027d
3 changed files with 262 additions and 121 deletions

View File

@@ -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}");
}
/// <summary>
/// 获取本机IP地址优先选择与实验板同网段的IP
/// </summary>
/// <returns>本机IP地址</returns>
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;
}
}
/// <summary>
/// 获取本机MAC地址
/// </summary>
/// <returns>本机MAC地址字节数组</returns>
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];
}
}
/// <summary>
/// 获取本机网络接口名称
/// </summary>
/// <returns>网络接口名称</returns>
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 "未知";
}
}
/// <summary>
/// 初始化ARP记录
/// </summary>
/// <returns>是否成功</returns>
private async Task<bool> InitializeArpAsync()
{
try
{
return await Arp.CheckOrAddAsync(BOARD_IP, BOARD_MAC, _localInterface);
}
catch (Exception ex)
{
logger.Error(ex, "初始化ARP记录失败");
return false;
}
}
/// <summary>
/// 获取主机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<IActionResult> 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
}
/// <summary>
/// 设置板卡MAC地址
/// 获取本机网络信息
/// </summary>
/// <param name="boardMac">板卡MAC地址格式AA:BB:CC:DD:EE:FF</param>
/// <returns>操作结果</returns>
[HttpPost("SetBoardMAC")]
/// <returns>本机网络信息</returns>
[HttpGet("GetLocalNetworkInfo")]
[EnableCors("Users")]
[ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> 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
});
}
/// <summary>