如何确定本地主机的 IPv4 地址?

Posted

技术标签:

【中文标题】如何确定本地主机的 IPv4 地址?【英文标题】:How do I determine the local host’s IPv4 addresses? 【发布时间】:2011-10-03 20:55:39 【问题描述】:

如何仅从Dns.GetHostAddresses() 获取Internet Protocol version 4 地址?我有下面的代码,它给了我 IPv4 和 IPv6 地址。 我必须让它与具有多个 IPv4 地址的盒子一起工作。

IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
private void get_IPs()
    
        foreach (IPAddress a in localIPs)
        
           server_ip = server_ip + a.ToString() + "/";
        
    

【问题讨论】:

【参考方案1】:

这是使用 for 循环查找第一个连接的 IPv4 的代码:

        IPAddress ipAddress = null;
        IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());           

        for (int i=0 ; i<localIPs.Length ; i++)
        
            if (localIPs[i].AddressFamily == AddressFamily.InterNetwork)
            
                ipAddress = localIPs[i];
                break;
                            
        

【讨论】:

【参考方案2】:

这是我的代码。 并且可以在许多 LAN 卡上找到它。

private string GetLocalIpAddress()

    string localIpAddress = string.Empty;
    NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();

    foreach (NetworkInterface nic in nics)
    
        if (nic.OperationalStatus != OperationalStatus.Up)
        
            continue;
        

        IPv4InterfaceStatistics adapterStat = (nic).GetIPv4Statistics();
        UnicastIPAddressInformationCollection uniCast = (nic).GetIPProperties().UnicastAddresses;

        if (uniCast != null)
        
            foreach (UnicastIPAddressInformation uni in uniCast)
            
                if (adapterStat.UnicastPacketsReceived > 0
                    && adapterStat.UnicastPacketsSent > 0
                    && nic.NetworkInterfaceType != NetworkInterfaceType.Loopback)
                
                    if (uni.Address.AddressFamily == AddressFamily.InterNetwork)
                    
                        localIpAddress = nic.GetIPProperties().UnicastAddresses[0].Address.ToString();

                        break;
                    
                
            
        
    

    return localIpAddress;

【讨论】:

【参考方案3】:

对我来说,更清洁的解决方案是:

 public static string GetLocalIP() 
        
            string ipv4Address = String.Empty;

            foreach (IPAddress currentIPAddress in Dns.GetHostAddresses(Dns.GetHostName()))
            
                if (currentIPAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                
                    ipv4Address = currentIPAddress.ToString();
                    break;
                
            

            return ipv4Address;
        

【讨论】:

此函数返回一个地址,但问题指出它必须支持具有多个 IPv4 地址的主机。【参考方案4】:

我使用了以

开头的答案
/// <summary> and it mostly worked:
//for some reason Visual Studio 2010 did not understand AddressFamily.Inernetwork
    if (address.Address.AddressFamily != AddressFamily.InterNetwork) 

我不得不使用:

if(address.Address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork)

但我实际使用过:

if(!address.Address.AddressFamily.Equals(System.Net.Sockets.AddressFamily.InterNetwork))

另外,我补充说:

if (network.OperationalStatus != OperationalStatus.Up)
                continue;

因为有些网络无法正常工作并且不应该存在,所以我确实看到它们在注册表中。 ---阿尔文

【讨论】:

【参考方案5】:

我使用这个帮助方法,在过滤掉 IPV6 和 Loopback 一次后返回第一个活动的 IPV4 地址


    public static IPAddress GetLocalIPAddress()
    
        IPAddress result = null;
        IPHostEntry iphostentry = Dns.GetHostEntry(Dns.GetHostName());
        IPAddress[] ipv4Address = Array.FindAll(iphostentry.AddressList, add => add.AddressFamily == AddressFamily.InterNetwork && !IPAddress.IsLoopback(add));
        if (ipv4Address.Length > 0 )
        
            result =ipv4Address[0];
        
        return result;
    

【讨论】:

【参考方案6】:

使用 Linq 时非常干净和甜美

IPAddress[] addresses = Dns.GetHostAddresses(Dns.GetHostName()).Where(a => a.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).ToArray();

【讨论】:

【参考方案7】:

这是我使用的一个函数:

public static string GetIP4Address()

    string IP4Address = String.Empty;

    foreach (IPAddress IPA in Dns.GetHostAddresses(Dns.GetHostName()))
    
        if (IPA.AddressFamily == AddressFamily.InterNetwork)
        
            IP4Address = IPA.ToString();
            break;
        
    

    return IP4Address;


作为可枚举:

public static IEnumerable<string> GetIP4Addresses()

    return Dns.GetHostAddresses(Dns.GetHostName())
        .Where(IPA => IPA.AddressFamily == AddressFamily.InterNetwork)
        .Select(x => x.ToString());

【讨论】:

我不建议与字符串进行比较,因为这需要通过反射查找枚举值并执行字符串比较。特别是因为您可以毫无问题地与枚举 AddressFamily.InterNetwork 进行比较。 此函数返回一个地址,但问题指出它必须支持具有多个 IPv4 地址的主机。【参考方案8】:

来自my blog:

/// <summary> 
/// This utility function displays all the IP (v4, not v6) addresses of the local computer. 
/// </summary> 
public static void DisplayIPAddresses() 
 
    StringBuilder sb = new StringBuilder(); 

    // Get a list of all network interfaces (usually one per network card, dialup, and *** connection) 
    NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces(); 

    foreach (NetworkInterface network in networkInterfaces) 
     
        // Read the IP configuration for each network 
        IPInterfaceProperties properties = network.GetIPProperties(); 

        // Each network interface may have multiple IP addresses 
        foreach (IPAddressInformation address in properties.UnicastAddresses) 
         
            // We're only interested in IPv4 addresses for now 
            if (address.Address.AddressFamily != AddressFamily.InterNetwork) 
                continue; 

            // Ignore loopback addresses (e.g., 127.0.0.1) 
            if (IPAddress.IsLoopback(address.Address)) 
                continue; 

            sb.AppendLine(address.Address.ToString() + " (" + network.Name + ")"); 
         
     

    MessageBox.Show(sb.ToString()); 

特别是,我推荐Dns.GetHostAddresses(Dns.GetHostName());,不管这句话在各种文章和博客上有多受欢迎。

【讨论】:

我很难用 Dns 获得正确的结果.....这正是我想要的。谢谢 之前在 Azure 中托管的网站遇到了问题。但是,这与您提到的 Dns.GetHostAddress 方法相比效果很好【参考方案9】:

来自MSDN on Dns.GetHostAddresses,

当一个空字符串作为主机名传递时,此方法返回 所有操作系统的本地主机的 IPv4 地址,除了 视窗服务器 2003;对于 Windows Server 2003,IPv4 和 IPv6 返回本地主机的地址。

从 GetHostAddresses 的结果中过滤 IPv6 地址 如果本地计算机没有安装 IPv6,则使用此方法。作为一个 结果,有可能取回一个空的 IPAddress 实例,只要 可用于 hostNameOrAddress.parameter 的 IPv6 结果。

所以,你可以用这个try and parse it:

IPAddress.TryParse

然后检查AddressFamily是哪个

为 IPv4 返回 System.Net.Sockets.AddressFamily.InterNetwork 或 用于 IPv6 的 System.Net.Sockets.AddressFamily.InterNetworkV6。

string input = "192.168.0.10";

IPAddress address;
if (IPAddress.TryParse(input, out address))

    switch (address.AddressFamily)
    
        case System.Net.Sockets.AddressFamily.InterNetwork:
            // we have IPv4
            break;
        case System.Net.Sockets.AddressFamily.InterNetworkV6:
            // we have IPv6
            break;
        default:
            // do something else
            break;
    

【讨论】:

【参考方案10】:

在您的代码中添加类似的内容

  if( IPAddress.Parse(a).AddressFamily == AddressFamily.InterNetwork )
  // IPv4 address

【讨论】:

foreach (IPAddress a in localIPs) if (a.IsIPv6LinkLocal == false) server_ip = server_ip + a.ToString() + "/"; 问题是我从这个方法收到了一个 169.254.x.x 地址。【参考方案11】:

locaIPs.Where(ip =&gt; ip.AddressFamily == AddressFamily.InterNetwork)

【讨论】:

以上是关于如何确定本地主机的 IPv4 地址?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 AWS 中确定子网 IPv4 CIDR 地址?

IPv4地址掩码

如何确定字符串是 C# 中的有效 IPv4 还是 IPv6 地址?

确定 IP 地址的网络和主机 ID 部分

IPv4 网络 ID 和主机 ID

为啥电脑固定了ip地址查看信息时发现ipv4地址不一样了