首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Dns.GetHostAddress和Dns.GetHostEntry都只返回ipv4地址。如何同时获得ipv4和ipv6地址?

Dns.GetHostAddress和Dns.GetHostEntry都只返回ipv4地址。如何同时获得ipv4和ipv6地址?
EN

Stack Overflow用户
提问于 2016-05-23 09:04:03
回答 1查看 1.7K关注 0票数 2

一个简单的问题被问到了hereherehere,但似乎没有一个答案有效,所以我发布了实际的代码,并显示在一台ipv6支持的机器上,希望有人能给出解决方案。

以下是这两个问题的代码

代码语言:javascript
运行
复制
using System;

public class HelloWorld
{
    static public void Main ()
    {
        string hostName = "google.com"; // uri.DnsSafeHost;
        Console.WriteLine("DNS.GetHostAddresses: " + hostName);
        var hostAddresses = System.Net.Dns.GetHostAddresses(hostName);
        Console.WriteLine("DNS.NumAddreses:" + hostAddresses.Length);
        foreach (System.Net.IPAddress hostAddress in hostAddresses)
        {
            Console.WriteLine(
                "addr: " + hostAddress.ToString() + 
                " family: " + hostAddress.AddressFamily.ToString());
        }


        System.Net.IPHostEntry ipHostEntry = System.Net.Dns.GetHostEntry(hostName);
        Console.WriteLine("DNS.GetHostEntry NumAddresses:" + ipHostEntry.AddressList.Length);
        foreach (System.Net.IPAddress hostAddress in ipHostEntry.AddressList)
        {
            Console.WriteLine(
                "addr: " + hostAddress.ToString() + 
                " family: " + hostAddress.AddressFamily.ToString());
        }
    }
}

我使用ipv6在Ubuntu14.04上运行它。以下是一些可能相关的信息

代码语言:javascript
运行
复制
# ip -6 addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
    inet6 2400:6180:0:d0::691:9001/64 scope global 
       valid_lft forever preferred_lft forever
    inet6 fe80::601:eeff:fe7e:201/64 scope link 
       valid_lft forever preferred_lft forever

证明Google.com有一个ipv6地址

代码语言:javascript
运行
复制
# dig google.com AAAA +short
2404:6800:4003:c00::8a

显示我可以直接在google.com的ipv6地址上ping

代码语言:javascript
运行
复制
# ping6 2404:6800:4003:c00::8a
PING 2404:6800:4003:c00::8a(2404:6800:4003:c00::8a) 56 data bytes
64 bytes from 2404:6800:4003:c00::8a: icmp_seq=1 ttl=58 time=2.25 ms
64 bytes from 2404:6800:4003:c00::8a: icmp_seq=2 ttl=58 time=2.12 ms
^C

显示我的单一版本

代码语言:javascript
运行
复制
# mono --version
Mono JIT compiler version 4.2.3 (Stable 4.2.3.4/832de4b Wed Mar 16 13:19:08 UTC 2016)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
    TLS:           __thread
    SIGSEGV:       altstack
    Notifications: epoll
    Architecture:  amd64
    Disabled:      none
    Misc:          softdebug 
    LLVM:          supported, not enabled.
    GC:            sgen
# mcs --version
Mono C# compiler version 4.2.3.0

编译并运行上面的示例

代码语言:javascript
运行
复制
# mcs dns.cs
# mono dns.exe
DNS.GetHostAddresses: google.com
DNS.NumAddreses:6
addr: 74.125.200.102 family: InterNetwork
addr: 74.125.200.139 family: InterNetwork
addr: 74.125.200.138 family: InterNetwork
addr: 74.125.200.101 family: InterNetwork
addr: 74.125.200.113 family: InterNetwork
addr: 74.125.200.100 family: InterNetwork
DNS.GetHostEntry NumAddresses:6
addr: 74.125.200.100 family: InterNetwork
addr: 74.125.200.113 family: InterNetwork
addr: 74.125.200.139 family: InterNetwork
addr: 74.125.200.102 family: InterNetwork
addr: 74.125.200.138 family: InterNetwork
addr: 74.125.200.101 family: InterNetwork

一些答案/评论建议.NET过滤掉仅在ipv4机器上的ipv6。这显然不是一台只有ipv4的机器。

注意:在同一台机器上用node.js做同样的事情。它正确地获取ipv6地址和ipv4地址。

代码语言:javascript
运行
复制
# node
> require('dns').lookup("google.com", {all:true}, (err, addresses) => { console.log(addresses); });
GetAddrInfoReqWrap {
  callback: { [Function: asyncCallback] immediately: true },
  family: 0,
  hostname: 'google.com',
  oncomplete: [Function: onlookupall],
  domain: 
   Domain {
     domain: null,
     _events: { error: [Function] },
     _eventsCount: 1,
     _maxListeners: undefined,
     members: [] } }
> [ { address: '74.125.200.101', family: 4 },
  { address: '74.125.200.138', family: 4 },
  { address: '74.125.200.102', family: 4 },
  { address: '74.125.200.139', family: 4 },
  { address: '74.125.200.113', family: 4 },
  { address: '74.125.200.100', family: 4 },
  { address: '2404:6800:4003:c00::65', family: 6 } ]

如何让DNS.GetHostAddressesDNS.GetHostEntry同时返回ipv6和ipv4地址?

EN

回答 1

Stack Overflow用户

发布于 2016-05-23 09:08:14

这是从MSDN站点(https://msdn.microsoft.com/en-us/library/system.net.ipaddress(v=vs.110).aspx )获取的,它展示了如何查找有关地址的所有相关信息,希望这可能会有所帮助:

代码语言:javascript
运行
复制
// This program shows how to use the IPAddress class to obtain a server 
// IP addressess and related information.

using System;
using System.Net;
using System.Net.Sockets;
using System.Text.RegularExpressions;

namespace Mssc.Services.ConnectionManagement
{

  class TestIPAddress 
  {

    /**
      * The IPAddresses method obtains the selected server IP address information.
      * It then displays the type of address family supported by the server and its 
      * IP address in standard and byte format.
      **/
    private static void IPAddresses(string server) 
    {
      try 
      {
        System.Text.ASCIIEncoding ASCII = new System.Text.ASCIIEncoding();

        // Get server related information.
        IPHostEntry heserver = Dns.GetHostEntry(server);

        // Loop on the AddressList
        foreach (IPAddress curAdd in heserver.AddressList) 
        {


          // Display the type of address family supported by the server. If the
          // server is IPv6-enabled this value is: InternNetworkV6. If the server
          // is also IPv4-enabled there will be an additional value of InterNetwork.
          Console.WriteLine("AddressFamily: " + curAdd.AddressFamily.ToString());

          // Display the ScopeId property in case of IPV6 addresses.
          if(curAdd.AddressFamily.ToString() == ProtocolFamily.InterNetworkV6.ToString())
            Console.WriteLine("Scope Id: " + curAdd.ScopeId.ToString());


          // Display the server IP address in the standard format. In 
          // IPv4 the format will be dotted-quad notation, in IPv6 it will be
          // in in colon-hexadecimal notation.
          Console.WriteLine("Address: " + curAdd.ToString());

          // Display the server IP address in byte format.
          Console.Write("AddressBytes: ");



          Byte[] bytes = curAdd.GetAddressBytes();
          for (int i = 0; i < bytes.Length; i++) 
          {
            Console.Write(bytes[i]);
          }                          

          Console.WriteLine("\r\n");

        }

      }
      catch (Exception e) 
      {
        Console.WriteLine("[DoResolve] Exception: " + e.ToString());
      }
    }

    // This IPAddressAdditionalInfo displays additional server address information.
    private static void IPAddressAdditionalInfo() 
    {
      try 
      {
        // Display the flags that show if the server supports IPv4 or IPv6
        // address schemas.
        Console.WriteLine("\r\nSupportsIPv4: " + Socket.SupportsIPv4);
        Console.WriteLine("SupportsIPv6: " + Socket.SupportsIPv6);

        if (Socket.SupportsIPv6)
        {
          // Display the server Any address. This IP address indicates that the server 
          // should listen for client activity on all network interfaces. 
          Console.WriteLine("\r\nIPv6Any: " + IPAddress.IPv6Any.ToString());

          // Display the server loopback address. 
          Console.WriteLine("IPv6Loopback: " + IPAddress.IPv6Loopback.ToString());

          // Used during autoconfiguration first phase.
          Console.WriteLine("IPv6None: " + IPAddress.IPv6None.ToString());

          Console.WriteLine("IsLoopback(IPv6Loopback): " + IPAddress.IsLoopback(IPAddress.IPv6Loopback));
        }
        Console.WriteLine("IsLoopback(Loopback): " + IPAddress.IsLoopback(IPAddress.Loopback));
      }
      catch (Exception e) 
      {
        Console.WriteLine("[IPAddresses] Exception: " + e.ToString());
      }
    }


    public static void Main(string[] args) 
    {
      string server = null;

      // Define a regular expression to parse user's input.
      // This is a security check. It allows only
      // alphanumeric input string between 2 to 40 character long.
      Regex rex = new Regex(@"^[a-zA-Z]\w{1,39}$");

      if (args.Length < 1)
      {
        // If no server name is passed as an argument to this program, use the current 
        // server name as default.
        server = Dns.GetHostName();
        Console.WriteLine("Using current host: " + server);
      }
      else
      {
        server = args[0];
        if (!(rex.Match(server)).Success)
        {
          Console.WriteLine("Input string format not allowed.");
          return;
        }
      }

      // Get the list of the addresses associated with the requested server.
      IPAddresses(server);

      // Get additonal address information.
      IPAddressAdditionalInfo();
    }

  }
}

编辑

在我的Win 10机器上的研究表明,IPv6地址只返回本地主机,而不返回带有GetHostEntry或GetHostAddresses的internet主机。会看得更远。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37386839

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档