GetHostEntry和GetHostByName之间的差异

本文关键字:之间 GetHostByName GetHostEntry | 更新日期: 2023-09-27 18:26:09

在MSDN上,它提到GetHostByName已经过时。替换为GetHostEntry。他们有什么不同?

GetHostEntry和GetHostByName之间的差异

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

首先,重要的是要认识到这些是UNIX套接字库的包装器,它公开了函数inet_aton(相当于IPAddress.Parse)、gethostbyname(由Dns.GetHostByName包装)和gethostbyaddr(由Dns.GetHostByAddress包装)。微软随后在此基础上添加了Dns.GetHostEntry实用程序功能。

在思考了Dns.GetHostByNameDns.GetHostEntry之间的哲学差异之后,我得出的结论是,微软决定他们为DNS查找公开的主要API应该尝试仅返回实际DNS条目

在UNIX套接字级别,gethostbyname可以采用IP地址或主机名。如果您提供的是IP地址,那么它被明确地记录为解析IP地址。但它也被明确记录为只支持IPv4地址。因此,我们鼓励开发人员使用函数getaddrinfo,它可以进行更复杂的查找,包括您想要连接的服务,并且支持IPv4以外的地址族。

微软在包装上采取了不同的方法。他们仍然认为GetHostByName是不可取的,但他们决定创建一个函数,返回您要求的实际物理DNS主机条目,而不是将查找绑定到服务数据库。仅仅提供一个包含有效地址的字符串是不够的,如果没有DNS条目,那么GetHostEntry就会失败,因为这就是它的全部目的。因此,如果将主机名传递到GetHostEntry,它将执行正向DNS查找,如果将IP地址传递到GetHostEntry,则它将执行反向DNS查找。无论哪种方式,返回的结构都会告诉你DNS条目名称和相关地址——,但如果没有相关条目,你得到的唯一信息就是错误。

如果您希望处理为连接提供目标的用户输入,GetHostEntry实际上并不合适,因为如果用户键入一个特定的IP地址,它可能无法解决它,即使由于它是一个IP地址,您拥有建立连接所需的一切。在这种情况下,GetHostByName正是你需要的函数,但微软选择了弃用它。考虑到弃用,习惯用法将是复制@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();