7

MSDN上,它提到GetHostByName已过时。替换是GetHostEntry. 他们有什么区别?

4

2 回答 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;
}
于 2012-04-12T20:35:03.777 回答
2

首先,重要的是要认识到这些是 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();
于 2019-06-03T21:20:17.240 回答