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
不太适合于用户输入的目标地址的通用处理。