GetHostEntry和GetHostByName之间有什么区别?

7

MSDN上提到GetHostByName已经过时,替代方法是GetHostEntry。它们有什么区别?

2个回答

9

看起来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;
}

1
如果你像我一样遇到了那些过时的错误,你可以在你的代码中很容易地将 GetHostByName() 更改为 GetHostEntry() - Aryo
这并不是那么简单。即使IP地址有效,如果无法执行反向DNS查找,GetHostByAddress也会失败。粗略地说,前端的GetHostEntry旨在仅返回_实际的DNS条目_,而GetHostByName旨在以任何方式提供IP地址。因此,您传递给GetHostByName的任何IP地址都将被解析并返回,但是只有在您可以获得反向DNS响应时,GetHostEntry才会将该IP返回给您。这使得GetHostEntry不太适合用于处理来自用户输入的目标地址的通用处理。 - Jonathan Gilbert

2
首先,重要的是要认识到这些是UNIX套接字库的包装器,其公开函数inet_aton(相当于IPAddress.Parse),gethostbyname(由Dns.GetHostByName包装)和gethostbyaddr(由Dns.GetHostByAddress包装)。Microsoft随后基于这些添加了Dns.GetHostEntry实用程序函数。
在思考Dns.GetHostByNameDns.GetHostEntry之间的哲学差异后,我得出结论,微软决定他们暴露给DNS查找的主要API应该尝试只返回实际的DNS条目
在UNIX套接字级别上,gethostbyname可以使用IP地址或主机名。如果您提供IP地址,则它明确记录为解析IP地址。但是,它也明确记录为仅支持IPv4地址。因此,鼓励开发人员改用函数getaddrinfo,它执行更复杂的查找,涉及您要连接的服务以及支持除IPv4之外的地址族。
微软在其包装器中采用了不同的方法。他们仍然认为GetHostByName已过时,但是他们没有将查找与服务数据库绑定,而是决定创建一个函数,返回您要求的实际物理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);

这个方法使用了类的内部实现细节,但是它的精神很容易在你自己的代码中复制,例如: // 最初的回答
if (!IPAddress.TryParse(userInput, out var addressToWhichToConnect))
  addressToWhichToConnect = Dns.GetHostEntry(userInput).AddressList.First();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接