Во-первых, важно понимать, что это оболочки библиотеки сокетов 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();