应使用 networkinterface.getallnetworkinterfaces() 遍历启用的物理网卡(operationalstatus.up 且类型为 ethernet/wireless80211),筛选其 ipv4 单播地址,并通过 isipv4private 判断是否属于 10.0.0.0/8、172.16.0.0/12 或 192.168.0.0/16 私有地址段。

怎么用 Dns.GetHostAddresses 获取本机局域网 IP(但别信 localhost)
直接调 Dns.GetHostAddresses(Dns.GetHostName()) 很容易拿到 127.0.0.1 或 IPv6 回环地址,这不是你想要的局域网 IP。真正有效的做法是:先获取所有本机 IP,再过滤出 IPv4 且非回环、非未分配(0.0.0.0)、且属于私有地址段的地址。
私有地址段包括:10.0.0.0/8、172.16.0.0/12、192.168.0.0/16 —— 这些才是典型局域网 IP 的范围。
实操建议:
- 别依赖主机名解析,它可能指向
127.0.0.1(尤其 hosts 文件被改过时) - 用
NetworkInterface.GetAllNetworkInterfaces()更可靠,能区分物理网卡、虚拟网卡、已禁用接口 - 优先检查
OperationalStatus.Up和NetworkInterfaceType.Ethernet/Wireless80211,跳过 Loopback、Tunnel、Unknown 类型
用 NetworkInterface 枚举适配器并提取 IPv4 地址
这是最可控的方式:遍历所有启用的网络适配器,逐个检查其 UnicastAddresses,筛选出 IPv4 的有效地址。
关键判断逻辑:
- 适配器状态必须是
OperationalStatus.Up - 类型避开
NetworkInterfaceType.Loopback、NetworkInterfaceType.Tunnel、NetworkInterfaceType.Ppp - IP 地址需满足:
AddressFamily == AddressFamily.InterNetwork且IsIPv4Private(address)(需自行实现私有地址判断) - 注意:有些虚拟网卡(如 VMware、Docker、WSL2)也会暴露 IPv4 地址,要按业务需要决定是否排除 —— 比如只取物理以太网或 Wi-Fi
示例片段(判断是否为私有 IPv4):
static bool IsIPv4Private(IPAddress addr)
{
var bytes = addr.GetAddressBytes();
return bytes[0] == 10 ||
(bytes[0] == 172 && bytes[1] >= 16 && bytes[1]
<h3>为什么 <code>GetAllNetworkInterfaces</code> 返回的 IP 有时是空的?</h3>
<p>常见原因不是代码写错,而是权限或系统状态问题:</p>
- 在 .NET Core / .NET 5+ 中,Linux/macOS 下需确保进程有读取网络接口信息的权限(例如 Linux 上可能需
cap_net_raw,但通常不需要;更常见的是 Docker 容器未加--network host或未挂载/sys/class/net) - Windows 上如果禁用了“网络连接”服务(Network Connections service),
NetworkInterface可能无法枚举真实适配器 - 某些精简版系统(如 Windows Nano Server、IoT Core)不支持完整网络接口 API,会返回空数组
- WSL2 默认走虚拟 NAT 网络,主系统看到的是
vEthernet (WSL)适配器,其 IPv4 是内网地址(如172.x.x.x),不是宿主机真实网卡 IP
生产环境该选哪个 IP?别只拿第一个
一台机器常有多个有效局域网 IP(比如同时连着有线和 Wi-Fi,或开了热点),直接取列表第一个极不可靠。
- 优先级建议:有线 > Wi-Fi > 其他;可通过
NetworkInterface.NetworkInterfaceType和NetworkInterface.Description(含 “Ethernet”、“Realtek”、“Intel”、“Wi-Fi”、“Wireless” 等关键词)辅助判断 - 若需绑定监听(如
HttpListener或Kestrel),推荐用IPAddress.Any(0.0.0.0)而不是具体 IP,避免绑定失败 - 若必须返回一个“代表本机”的 IP 给外部调用方(如 API 返回服务器地址),应记录日志并允许配置 fallback 策略(例如查不到就抛异常 or 返回 null,而不是硬塞
127.0.0.1)
真正麻烦的不是怎么取,而是取到之后怎么解释它 —— 同一个 IP,在不同网络拓扑下对客户端可能是不可达的。这点经常被忽略。










