【问题标题】:How do I determine the local host’s IPv4 addresses?如何确定本地主机的 IPv4 地址?
【发布时间】: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() + "/";
        }
    }

【问题讨论】:

    标签: c# ip-address ipv4


    【解决方案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 VPN 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)

                【讨论】:

                  猜你喜欢
                  • 2020-12-10
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-04-22
                  • 2022-06-28
                  • 1970-01-01
                  • 2012-12-25
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多