Разница между GetHostEntry и GetHostByName? - PullRequest
7 голосов
/ 28 февраля 2012

Вкл. MSDN упоминается GetHostByName устарело. Замена GetHostEntry. В чем их разница?

Ответы [ 2 ]

8 голосов
/ 13 апреля 2012

Похоже, что GetHostEntry немного больше проверяет ошибки и также поддерживает Трассировка сети

GetHostByName декомпилировано:

public static IPHostEntry GetHostByName(string hostName)
{
  if (hostName == null)
    throw new ArgumentNullException("hostName");
  Dns.s_DnsPermission.Demand();
  IPAddress address;
  if (IPAddress.TryParse(hostName, out address))
    return Dns.GetUnresolveAnswer(address);
  else
    return Dns.InternalGetHostByName(hostName, false);
}

GetHostEntry Декомпилировано:

public static IPHostEntry GetHostEntry(string hostNameOrAddress)
{
  if (Logging.On)
    Logging.Enter(Logging.Sockets, "DNS", "GetHostEntry", hostNameOrAddress);
  Dns.s_DnsPermission.Demand();
  if (hostNameOrAddress == null)
    throw new ArgumentNullException("hostNameOrAddress");
  IPAddress address;
  IPHostEntry ipHostEntry;
  if (IPAddress.TryParse(hostNameOrAddress, out address))
  {
    if (((object) address).Equals((object) IPAddress.Any) || ((object) address).Equals((object) IPAddress.IPv6Any))
      throw new ArgumentException(SR.GetString("net_invalid_ip_addr"), "hostNameOrAddress");
    ipHostEntry = Dns.InternalGetHostByAddress(address, true);
  }
  else
    ipHostEntry = Dns.InternalGetHostByName(hostNameOrAddress, true);
  if (Logging.On)
    Logging.Exit(Logging.Sockets, "DNS", "GetHostEntry", (object) ipHostEntry);
  return ipHostEntry;
}
0 голосов
/ 04 июня 2019

Во-первых, важно понимать, что это оболочки библиотеки сокетов UNIX, которая предоставляет функции inet_aton (эквивалентные IPAddress.Parse), gethostbyname (обернутые Dns.GetHostByName) и gethostbyaddr (обернутыена Dns.GetHostByAddress).Впоследствии Microsoft добавила на их основе служебную функцию Dns.GetHostEntry.

Обдумав философское различие между Dns.GetHostByName и Dns.GetHostEntry, я пришел к выводу, что Microsoft решила, что основной API, который они предоставляютПри поиске DNS следует пытаться вернуть только фактические записи DNS .

На уровне сокетов UNIX gethostbyname может принимать либо IP-адрес, либо имя хоста.Это явно задокументировано как разбор IP-адреса, если это то, что вы предоставляете.Но он также явно задокументирован как поддерживающий только адреса IPv4.Поэтому разработчикам рекомендуется использовать вместо этого функцию getaddrinfo, которая выполняет более сложный поиск, включающий также службу, к которой вы хотите подключиться, и которая поддерживает семейства адресов, отличные от IPv4.

Microsoftпо-другому подходил в их обертке.Они по-прежнему считают GetHostByName устаревшим, но вместо того, чтобы связать поиск с базой данных служб, они решили создать функцию, которая возвращает фактическую запись физического узла DNS, которую вы запрашиваете.Недостаточно, чтобы вы указали строку с допустимым адресом в ней, если нет записи DNS, то GetHostEntry завершится неудачей, потому что это и есть ее цель.Таким образом, если вы передаете имя хоста в GetHostEntry, он выполняет прямой DNS-поиск, а если вы передаете IP-адрес в GetHostEntry, он выполняет обратный DNS-поиск.В любом случае, возвращенная структура сообщит вам как имя DNS-записи, так и связанный с ней адрес - , но , если нет связанной записи, единственное, что вы получите, - это ошибка.

Если вы хотите обрабатывать пользовательский ввод, который предоставляет цель для соединения, GetHostEntry не очень подходит, потому что, если пользователь вводит специальный IP-адрес, он может не разрешить его, даже если это IP-адрес, у вас есть все необходимое для установления соединения.GetHostByName - это именно та функция, которая вам нужна в этом случае, но Microsoft решила отказаться от нее.С учетом устаревания, идиома будет заключаться в том, чтобы повторить подход «попытаться проанализировать первым», который @Faisai Mansoor продемонстрировал в декомпилированной функции GetHostByName:

// Microsoft's internal code for GetHostByName:
if (IPAddress.TryParse(hostName, out address))
  return Dns.GetUnresolveAnswer(address);
else
  return Dns.InternalGetHostByName(hostName, false);

При этом используются внутренние детали реализации Dns класс, но дух этого легко воспроизвести в вашем собственном коде, например:

if (!IPAddress.TryParse(userInput, out var addressToWhichToConnect))
  addressToWhichToConnect = Dns.GetHostEntry(userInput).AddressList.First();
...