Преобразование DNS-имени в IP-адрес ... Какой из многих IP-адресов мне выбрать? - PullRequest
0 голосов
/ 09 ноября 2018

Преобразовать имя хоста в IP-адреса просто:

foreach (var hostName in new [] { "github.com", "microsoft.com", "google.com", "stackoverflow.com" })
{
    var ipAddresses = Dns.GetHostAddresses(hostName);

    Console.WriteLine($"=== {hostName}");
    Console.WriteLine(string.Join(Environment.NewLine, ipAddresses.Select(ip => ip.ToString())));
    Console.WriteLine();
}

enter image description here

Если я теперь хочу выбрать один IP-адрес , чтобы установить соединение (и записать этот точный IP-адрес), как бы я его выбрал?

Осложнения:

  1. Может быть несколько IP-адресов.
  2. Может быть несколько семейств адресов (IPv4 и IPv6).
  3. IPv6-адреса могут быть возвращены, но система может не поддерживать IPv6.

Есть ли приемлемый или рекомендуемый способ выбрать один?

Ответы [ 2 ]

0 голосов
/ 10 ноября 2018

Во время моего исследования я обнаружил следующие важные аспекты:

  1. Некоторые источники рекомендуют использовать IP-адреса в порядке, возвращаемом распознавателем и ОС.
  2. Таким образом, могут быть разработаны умные решения DNS, которые распределяют нагрузку на основе IP-адреса клиента, но также позволяют клиенту переключаться на более удаленный IP-адрес.
  3. Клиент может просто выбрать первый IP-адрес, если избыточность не требуется. Это может быть опасно, если сначала возвращается адрес IPv6, но IPv6 не поддерживается. Интернет-источники говорят, что многие неискушенные клиенты используют этот подход.
  4. Клиент может попробовать адреса в порядке избыточности. Управление таймаутами становится здесь более важным. По-видимому, это делают браузеры.
  5. В зависимости от того, поддерживаются ли IPv4 и / или IPv6, имеет смысл отфильтровать адреса неподдерживаемого семейства адресов.
  6. Патрик Мевзек предложил отдать предпочтение IPv6 при поддержке, чтобы помочь принятию IPv6.
  7. Иногда невозможно определить, доступен ли IPv6 или нет, за исключением попытки подключения. Чтобы минимизировать задержку соединения, приложение может соединяться, используя IPv4 и IPv6 параллельно. Это называется Счастливые глазные яблоки .

.NET Framework реализует следующий алгоритм в Socket.Connect(string hostName, int port): он разрешает все IP-адреса, отфильтровывает неподдерживаемые семейства адресов и пытается подключиться к ним по порядку. Этот алгоритм кажется лучшим для меня. TcpClient.Connect(string hostName, int port) делает нечто подобное, что я не могу полностью расшифровать.

0 голосов
/ 09 ноября 2018

Это выберет первый IP-адрес для каждого хоста.

foreach (var hostName in new[] { "github.com", "microsoft.com", "google.com", "stackoverflow.com" })
{
    var ipAddresses = Dns.GetHostAddresses(hostName);

    Console.WriteLine($"=== {hostName}");
    Console.WriteLine(ipAddresses.FirstOrDefault());
    Console.WriteLine();
}
...