商城首页欢迎来到中国正版软件门户

您的位置:首页 >C#怎么获取本机的局域网IP_C#如何读取网络适配器【干货】

C#怎么获取本机的局域网IP_C#如何读取网络适配器【干货】

  发布于2026-05-02 阅读(0)

扫一扫,手机访问

应使用 NetworkInterface.GetAllNetworkInterfaces() 遍历启用的物理网卡

获取本机局域网IP,一个更稳妥的路径是:调用 NetworkInterface.GetAllNetworkInterfaces(),遍历那些状态为启用(OperationalStatus.Up)且类型为有线以太网(Ethernet)或无线网络(Wireless80211)的物理网卡。接着,筛选出它们的IPv4单播地址,并通过一个私有地址判断函数(IsIPv4Private)来确认其是否属于 10.0.0.0/8172.16.0.0/12192.168.0.0/16 这三个典型的私有地址段。

C#怎么获取本机的局域网IP_C#如何读取网络适配器【干货】

怎么用 Dns.GetHostAddresses 获取本机局域网 IP(但别信 localhost)

直接调用 Dns.GetHostAddresses(Dns.GetHostName()) 听起来很直接,对吧?但这里有个常见的“坑”:它很容易返回 127.0.0.1 或者IPv6的回环地址,而这些显然不是你想要的局域网IP。真正有效的做法,其实是分两步走:先拿到本机所有的IP地址,然后从中过滤出那些符合IPv4协议、非回环地址、非未分配地址(0.0.0.0),并且落在私有地址段内的。

说到私有地址段,就是下面这三个大家伙:10.0.0.0/8172.16.0.0/12192.168.0.0/16 —— 它们才是局域网IP的“合法”活动范围。

这里有几个实操建议,可以帮你避开弯路:

  • 别过度依赖主机名解析,它可能被系统配置(比如hosts文件)指向 127.0.0.1
  • 相比之下,NetworkInterface.GetAllNetworkInterfaces() 更可靠,因为它能清晰地区分物理网卡、虚拟网卡,甚至是已禁用的接口。
  • 筛选时,优先检查网卡的 OperationalStatus.Up 状态和 NetworkInterfaceType.EthernetWireless80211 类型,主动跳过那些回环(Loopback)、隧道(Tunnel)或未知(Unknown)类型的接口。

NetworkInterface 枚举适配器并提取 IPv4 地址

这是目前最可控、最细致的方式。核心思路是遍历所有启用的网络适配器,挨个检查它们的 UnicastAddresses 集合,从中挑出符合条件的IPv4地址。

整个流程有几个关键判断点,缺一不可:

  • 适配器的运行状态必须是 OperationalStatus.Up
  • 适配器类型要避开 LoopbackTunnelPpp 这些通常不承载局域网流量的类型。
  • IP地址本身需要满足两个条件:地址族是 AddressFamily.InterNetwork(即IPv4),并且通过自定义的 IsIPv4Private(address) 函数判断为私有地址。
  • 需要特别留意的是,虚拟网卡(比如VMware、Docker、WSL2创建的)也会暴露IPv4地址。这就要根据你的具体业务需求来决定是否排除——例如,如果只想获取物理有线或无线网卡的IP,就需要额外过滤。

下面是一个判断IPv4地址是否为私有地址的示例函数:

static bool IsIPv4Private(IPAddress addr)
{
    var bytes = addr.GetAddressBytes();
    return bytes[0] == 10 ||
           (bytes[0] == 172 && bytes[1] >= 16 && bytes[1] <= 31) ||
           (bytes[0] == 192 && bytes[1] == 168);
}

为什么 GetAllNetworkInterfaces 返回的 IP 有时是空的?

代码明明写对了,但有时就是拿不到IP,问题出在哪?通常,原因不在代码逻辑,而在运行环境或系统状态:

  • 在 .NET Core / .NET 5+ 跨平台运行时,Linux或macOS下需要确保进程有读取网络接口信息的权限。虽然Linux上通常不需要特殊权限,但在Docker容器内运行时,如果未使用 --network host 模式或未挂载 /sys/class/net 目录,就可能无法获取信息。
  • 在Windows系统上,如果“网络连接”服务(Network Connections service)被禁用,NetworkInterface 相关API可能无法枚举到真实的网络适配器。
  • 某些精简版或嵌入式系统(如Windows Nano Server、IoT Core)可能不支持完整的网络接口API,调用后会返回空数组。
  • 对于WSL2用户,需要注意其默认使用虚拟NAT网络。在Windows宿主机上看到的对应 vEthernet (WSL) 适配器,其IPv4地址是内部网络地址(如 172.x.x.x),并非宿主机的真实物理网卡IP。

生产环境该选哪个 IP?别只拿第一个

一台机器上同时存在多个有效局域网IP的情况太常见了——比如同时连着有线网络和Wi-Fi,或者开启了移动热点。这时,如果简单地取返回列表里的第一个IP,可靠性就非常低。

  • 关于优先级,一个常见的经验法则是:有线网络(Ethernet)优先于无线网络(Wi-Fi),再优先于其他类型。可以通过检查 NetworkInterface.NetworkInterfaceTypeNetworkInterface.Description 属性(其中可能包含 “Ethernet”、“Realtek”、“Intel”、“Wi-Fi”、“Wireless” 等关键词)来辅助判断。
  • 如果需要绑定IP进行监听(例如使用 HttpListenerKestrel),更推荐使用 IPAddress.Any(即 0.0.0.0)来绑定所有可用接口,而不是绑定到某个具体IP,这样可以避免因特定网卡不可用而导致的绑定失败。
  • 如果必须选出一个“代表本机”的IP地址返回给外部调用方(比如在API响应中返回服务器地址),那么一定要记录日志,并且设计好回退(fallback)策略。例如,查不到合适IP时就返回null或抛出明确异常,而不是硬塞一个 127.0.0.1 给调用方。

话说回来,获取IP地址本身往往不是最麻烦的。真正的挑战在于,获取之后如何理解和解释它——同一个IP地址,在不同的网络拓扑和防火墙规则下,对客户端而言完全可能是不可达的。这一点,恰恰是最容易被忽略的关键所在。

本文转载于:https://www.php.cn/faq/2312597.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注