C# GetHostEntry和GetHostByName之间的区别?

C# GetHostEntry和GetHostByName之间的区别?,c#,dns,gethostbyname,C#,Dns,Gethostbyname,上面提到的GetHostByName已经过时。替换为GetHostEntry。他们的区别是什么 看起来GetHostEntry执行了更多的错误检查,并且还支持 已反编译GetHostByName: public static IPHostEntry GetHostByName(string hostName) { if (hostName == null) throw new ArgumentNullException("hostName"); Dns.s_DnsPermissi

上面提到的
GetHostByName
已经过时。替换为
GetHostEntry
。他们的区别是什么

看起来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);
}
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;
}
GetHostEntry已反编译:

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);
}
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\u aton
(相当于
IPAddress.Parse
)、
gethostbyname
(由
Dns.gethostbyname
包装)和
gethostbyaddr
(由
Dns.GetHostByAddress
包装)。Microsoft随后基于这些添加了
Dns.GetHostEntry
实用程序函数

在思考了
Dns.GetHostByName
Dns.GetHostEntry
之间的哲学区别之后,我得出了这样的结论:微软决定,他们为Dns查找公开的主要API应该只返回实际的Dns条目

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

微软在包装器中采用了不同的方法。他们仍然认为<>代码> GeToStByNeNe/CODE >被弃用,但他们不是将查找绑定到服务数据库,而是决定创建一个函数,返回请求的实际物理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();

如果你发现自己和我一样有这些过时的错误,你可以在你的代码上用
GetHostEntry()
轻松地更改
GetHostByName()
GetHostByAddress
如果无法执行反向DNS查找,则即使在有效的IP上也会失败。粗略地说,前端
GetHostEntry
的目标似乎是只返回实际的DNS条目,而
GetHostByName
的目标是以任何方式提供IP地址。因此,您传递给
GetHostByName
的任何IP地址都将被简单地解析并返回,但是
GetHostEntry
只有在您能够获得反向DNS响应的情况下才会返回该IP。这使得
GetHostEntry
不太适合于用户输入的目标地址的通用处理。