LOGO 首页 OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 技术文档 其他文档  
 
网站管理员

C# 获取本机 IP 地址:内网IP、公网IP,多种方法一次搞定

admin
2026年9月7日 19:12 本文热度 161

一、背景

在开发客户端应用、网络工具或需要进行设备标识时,获取本机的 IP 地址是一个常见需求。但“本机 IP”其实包含两个概念:

  • 内网 IP(局域网 IP):
     由路由器分配的私有地址,如 192.168.x.x10.x.x.x,用于局域网通信。
  • 公网 IP(外网 IP):
     互联网上唯一的公共地址,用于对外访问。

本文分别介绍这两种 IP 的获取方法,并提供 C# 开箱即用的代码。

二、获取内网 IP 地址

2.1 方法一:使用 Dns.GetHostEntry(最常用)

通过获取本地主机名,再解析其所有 IP 地址,从中筛选 IPv4 地址。

using System;
using System.Net;
using System.Linq;

public static string GetLocalIPv4()
{
    string hostName = Dns.GetHostName();
    IPAddress[] addresses = Dns.GetHostEntry(hostName).AddressList;
    IPAddress ipv4 = addresses.FirstOrDefault(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork);
    return ipv4?.ToString() ?? "未检测到 IPv4 地址";
}

2.2 方法二:使用 NetworkInterface 获取活跃网卡 IP

该方法可以过滤掉回环地址、虚拟网卡等,更贴近实际使用的网卡。

using System.Net;
using System.Net.NetworkInformation;
using System.Linq;

public static string GetActiveLocalIPv4()
{
    var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces()
        .Where(n => n.OperationalStatus == OperationalStatus.Up && n.NetworkInterfaceType != NetworkInterfaceType.Loopback)
        .Select(n => n.GetIPProperties())
        .SelectMany(p => p.UnicastAddresses)
        .Where(a => a.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
        .Select(a => a.Address)
        .FirstOrDefault();

    return networkInterfaces?.ToString() ?? "未检测到活跃 IPv4 地址";
}

2.3 方法三:获取本机所有 IPv4 地址(包括多个网卡)

public static List<string> GetAllLocalIPv4()
{
    string hostName = Dns.GetHostName();
    return Dns.GetHostEntry(hostName).AddressList
        .Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
        .Select(ip => ip.ToString())
        .ToList();
}

三、获取公网 IP 地址

内网 IP 无法在互联网上直接访问,因此需要借助外部服务来获取公网 IP。推荐使用 ip9.com.cn 的免费 API。

3.1 接口说明

直接调用 https://ip9.com.cn/get 即可返回当前请求的公网 IP 及归属地信息。

3.2 C# 实现

using System;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;

public class PublicIpClient
{
    private static readonly HttpClient _http = new HttpClient { Timeout = TimeSpan.FromSeconds(10) };

    /// <summary>
    /// 获取公网 IP 地址(仅IP字符串)
    /// </summary>
    public static async Task<string> GetPublicIpAsync()
    {
        try
        {
            string url = "https://ip9.com.cn/get";
            var response = await _http.GetAsync(url);
            response.EnsureSuccessStatusCode();
            string json = await response.Content.ReadAsStringAsync();
            using var doc = JsonDocument.Parse(json);
            var root = doc.RootElement;
            if (root.TryGetProperty("data"out var data) && data.TryGetProperty("ip"out var ipElement))
            {
                return ipElement.GetString();
            }
            return null;
        }
        catch
        {
            return null;
        }
    }

    /// <summary>
    /// 获取公网 IP 完整信息(含归属地)
    /// </summary>
    public static async Task<PublicIpInfo> GetPublicIpInfoAsync()
    {
        try
        {
            string url = "https://ip9.com.cn/get";
            var response = await _http.GetAsync(url);
            response.EnsureSuccessStatusCode();
            string json = await response.Content.ReadAsStringAsync();
            var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
            var result = JsonSerializer.Deserialize<Ip9Response>(json, options);
            if (result?.Ret == 200)
            {
                return new PublicIpInfo
                {
                    Ip = result.Data.Ip,
                    Country = result.Data.Country,
                    Province = result.Data.Province,
                    City = result.Data.City,
                    Area = result.Data.Area,
                    Isp = result.Data.Isp
                };
            }
            return null;
        }
        catch
        {
            return null;
        }
    }
}

// 数据模型(与 ip9.com.cn 一致)
public class Ip9Response
{
    public int Ret { getset; }
    public Ip9Data Data { getset; }
}

public class Ip9Data
{
    public string Ip { getset; }
    public string Country { getset; }
    public string Province { getset; }
    public string City { getset; }
    public string Area { getset; }
    public string Isp { getset; }
}

public class PublicIpInfo
{
    public string Ip { getset; }
    public string Country { getset; }
    public string Province { getset; }
    public string City { getset; }
    public string Area { getset; }
    public string Isp { getset; }
}

四、综合使用示例

class Program
{
    static async Task Main(string[] args)
    {
        // 1. 获取内网 IP
        string localIp = GetLocalIPv4();
        string activeLocalIp = GetActiveLocalIPv4();
        var allLocalIps = GetAllLocalIPv4();

        Console.WriteLine($"内网 IP(简单): {localIp}");
        Console.WriteLine($"内网 IP(活跃网卡): {activeLocalIp}");
        Console.WriteLine($"所有内网 IP: {string.Join(", ", allLocalIps)}");

        // 2. 获取公网 IP
        string publicIp = await PublicIpClient.GetPublicIpAsync();
        var publicInfo = await PublicIpClient.GetPublicIpInfoAsync();

        Console.WriteLine($"公网 IP: {publicIp}");
        if (publicInfo != null)
        {
            Console.WriteLine($"归属地: {publicInfo.Country} {publicInfo.Province} {publicInfo.City} {publicInfo.Area}");
            Console.WriteLine($"运营商: {publicInfo.Isp}");
        }
    }
}

运行示例输出

内网 IP(简单): 192.168.1.100
内网 IP(活跃网卡): 192.168.1.100
所有内网 IP: 192.168.1.100, 172.17.0.1
公网 IP: 123.45.67.89
归属地: 中国 浙江省 杭州市 西湖区
运营商: 中国电信

五、生产环境最佳实践

5.1 缓存公网 IP

公网 IP 一般不会频繁变化,可以在应用启动时获取一次并缓存,避免频繁调用外部 API。

public static class PublicIpCache
{
    private static string _cachedIp;
    private static DateTime _cacheTime;
    private static readonly TimeSpan _cacheDuration = TimeSpan.FromHours(1);

    public static async Task<string> GetPublicIpAsync()
    {
        if (_cachedIp != null && DateTime.Now - _cacheTime < _cacheDuration)
            return _cachedIp;

        var ip = await PublicIpClient.GetPublicIpAsync();
        if (!string.IsNullOrEmpty(ip))
        {
            _cachedIp = ip;
            _cacheTime = DateTime.Now;
        }
        return ip;
    }
}

5.2 降级处理

如果公网 API 不可用,可以尝试备选方案(如 ip-api.com)或返回“未知”。

5.3 注意内网 IP 多网卡情况

使用 NetworkInterface 方式时,务必检查网卡状态和类型,避免获取到虚拟网卡、回环地址等无效 IP。

六、总结

场景
推荐方法
简单获取一个内网 IPv4
Dns.GetHostEntry
 + 过滤 IPv4
获取真实活跃网卡的 IP
NetworkInterface
 过滤
获取所有内网 IP
Dns.GetHostEntry
 + 全部取回
获取公网 IP
调用 ip9.com.cn API(免费、无需注册)

以上代码均可在 .NET 6+ 项目中直接使用,无需额外引用第三方库。


该文章在 2026/9/9 10:52:30 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved  粤ICP备13012886号-1  粤公网安备44030602007207号