最常用方法是用Dns.GetHostAddresses获取所有IP后筛选IPv4且非回环地址,避免直接取首个结果导致拿到127.0.0.1或IPv6;多网卡时建议用NetworkInterface进一步按状态和类型精确筛选。

用 Dns.GetHostAddresses 获取本机局域网 IP(最常用)
多数场景下,你真正需要的是本机在局域网中的 IPv4 地址(比如启动本地 HTTP 服务、显示调试信息),Dns.GetHostAddresses 是最直接的方案。它通过主机名查本机所有绑定的 IP,再过滤出 IPv4 和非回环地址。
常见错误是直接取第一个结果——可能拿到 127.0.0.1 或 IPv6 地址,导致服务无法被其他设备访问。
- 必须显式筛选
AddressFamily.InterNetwork(即 IPv4) - 跳过
IPAddress.IsLoopback(ip)判断为 true 的地址(如127.0.0.1、::1) - 若机器有多个网卡(如 WiFi + 以太网 + Docker 虚拟网卡),会返回多个有效 IPv4,通常取第一个非回环的即可,但生产环境建议按网卡名或路由表进一步筛选
示例代码片段:
var host = Dns.GetHostEntry(Dns.GetHostName());
var ip = host.AddressList
.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork && !IPAddress.IsLoopback(ip));
// ip 可能为 null,记得判空
用 NetworkInterface 精确控制网卡筛选(需区分物理/虚拟网卡)
当 Dns.GetHostAddresses 返回了 Docker、Hyper-V、WSL2 等虚拟网卡的 IP(如 172.x.x.x 或 192.168.x.x 但不可达),而你只想取「真实有线/无线网卡」的地址时,必须用 NetworkInterface。
关键点在于:不能只看 IP 段,要结合网卡操作状态和类型判断。
- 过滤条件应包含:
ni.OperationalStatus == OperationalStatus.Up且ni.NetworkInterfaceType != NetworkInterfaceType.Loopback - 排除常见虚拟网卡:
ni.Name.Contains("Docker") || ni.Name.Contains("vEthernet") || ni.Name.Contains("WSL") -
UnicastAddresses中取IPv4地址,同样跳过IsLoopback
注意:Windows 上部分网卡(如某些蓝牙共享网络)可能状态为 Up 但无 IPv4 地址,需额外判空 Address。
外网 IP 无法“本地获取”,必须调用公网 API(别信本地命令)
很多人误以为 ipconfig 或 netstat 能查到外网 IP——其实它们只显示 NAT 后的内网地址。你家路由器的 WAN 口 IP 才是外网 IP,本机根本不知道,除非主动问公网服务器。
可靠做法是发起一次 HTTP 请求到可信的回显服务:
- 推荐用
https://api.ipify.org(纯文本,响应快,无 CORS 限制,适合后台调用) - 备用可选
https://ifconfig.me/ip或https://icanhazip.com - 务必加超时(建议 ≤5s)和重试逻辑,公网请求不稳定;首次调用失败不等于没网,可能是 DNS 或临时丢包
- 别用国内某些所谓“IP 查询站”,存在响应慢、返回 HTML、加广告、甚至劫持风险
示例(同步调用需注意线程阻塞):
using var client = new HttpClient();
var publicIp = await client.GetStringAsync("https://api.ipify.org").ConfigureAwait(false);
// publicIp 是字符串,如 "203.205.128.1"
IPv6 地址不是“更高级”,而是容易引发兼容性问题
如果你的代码默认接受 AddressFamily.InterNetworkV6,可能在以下场景出问题:
- 监听
HttpListener或Kestrel时,IPv6 地址绑定后,某些 Windows 防火墙策略默认不放行 IPv6 流量 - 局域网内其他设备(尤其是旧版 Android/iOS)可能未启用 IPv6,导致连不上
-
ping或浏览器输入[::1]这类格式容易输错,调试困难
除非明确业务要求支持 IPv6(如政企内网强制要求),否则建议默认只处理 IPv4,并在日志中明确标注「仅启用 IPv4 绑定」。混合模式(双栈)需额外验证两端协议栈是否一致。
真实项目里,IP 地址从来不是“取一个就行”,而是得结合用途、部署环境、网络拓扑来选——比如 Docker 容器里 Dns.GetHostAddresses 返回的常是 bridge 网络地址,和宿主机完全不是一回事。


















