在MSDN上,它提到GetHostByName
已过时。替换是GetHostEntry
. 他们有什么区别?
2 回答
看起来 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();