2016-05-23 7 views
0

simlar был задан вопрос here и here и here, но ни один из ответов не похоже на работу, так что я отправляю фактический код и показывая, что работает на ipv6, способной машины, надеясь кто-то может предложить решениеИ Dns.GetHostAddress, и Dns.GetHostEntry возвращают только адрес ipv4. Как получить оба адреса ipv4 и ipv6?

Вот код взято с обоих вопросов

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()); 
     } 
    } 
} 

Я запускаю его на Ubuntu 14.04 с ipv6. Вот некоторые, возможно, соответствующую информацию

# 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

# dig google.com AAAA +short 
2404:6800:4003:c00::8a 

Показать Я могу свистеть google.com непосредственно на его ipv6 адрес

# 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 

показать мою моно версию

# 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 

откомпилировать и запустить пример выше

# 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 отфильтровывает ipv6 на ipv4 только машины. Это явно не машина ipv4.

Примечание: здесь выполняется то же самое в node.js на той же машине. Он правильно получает адрес ipv6, а также ipv4 адреса

# 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.GetHostAddresses или DNS.GetHostEntry возвращать IPv4 и IPv6-адреса?

+0

Если это работает в MS.NET, а не в моно, сообщите об ошибке в http://bugzilla.xamarin.com/ – knocte

ответ

0

Это взято с сайта MSDN (https://msdn.microsoft.com/en-us/library/system.net.ipaddress(v=vs.110).aspx), он показывает, как найти всю необходимую информацию об адресах, мы надеемся, что может помочь:

// 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(); 
    } 

    } 
} 

EDIT

Исследования на моей Win 10 указывает, что адреса IPv6 возвращаются только для локальных хостов, а не для интернет-хостов с помощью GetHostEntry или GetHostAddresses. Посмотрим дальше.

+0

Не повезло, [вот результаты запуска этого примера] (http: // pastebin. ком/TDTK4yrm). note: Мне пришлось удалить проверку регулярного выражения. Он не позволяет '.', поэтому я не уверен, как вы должны ввести доменное имя?! ?? – gman