GetHostEntry和GetHostByName之间的差异
本文关键字:之间 GetHostByName GetHostEntry | 更新日期: 2023-09-27 18:26:09
在MSDN上,它提到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);
}
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.GetHostByName
和Dns.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();