문제

On MSDN it mentions GetHostByName is obsolete. The replacement is GetHostEntry. What are their difference?

도움이 되었습니까?

해결책

It looks like GetHostEntry does a little more error checking and also supports Network Tracing

GetHostByName Decompiled:

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 Decompiled:

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;
}

다른 팁

Firstly, it is important to recognize that these are wrappers of the UNIX socket library, which exposes functions inet_aton (equivalent to IPAddress.Parse), gethostbyname (wrapped by Dns.GetHostByName) and gethostbyaddr (wrapped by Dns.GetHostByAddress). Microsoft subsequently added the Dns.GetHostEntry utility function based on these.

After pondering the philosophical difference between Dns.GetHostByName and Dns.GetHostEntry, I've come to the conclusion that Microsoft decided that the primary API they expose for DNS lookups should be trying to return only actual DNS entries.

At the UNIX sockets level, gethostbyname can take either an IP address or a host name. It is explicitly documented as parsing the IP address if that's what you supply. But it is also explicitly documented as only supporting IPv4 addresses. As such, developers are encouraged to use the function getaddrinfo instead, which does a more complex look-up involving the service you want to connect to as well, and which supports address families other than IPv4.

Microsoft took a different approach in their wrapper. They still consider GetHostByName to be deprecated, but instead of tying the look-up to a services database, they decided to create a function that returns the actual physical DNS host entry you ask for. It's not enough that you perhaps supply a string with a valid address in it, if there's no DNS entry then GetHostEntry will fail, because that is its entire purpose. Thus, if you pass a host name into GetHostEntry, it performs a forward DNS lookup, and if you pass an IP address into GetHostEntry, it performs a reverse DNS lookup. Either way, the returned structure will tell you both the DNS entry name and the associated address -- but if there is no associated entry, the only thing you get back is an error.

If you're looking to handle user input that supplies a target for connection, GetHostEntry is not really suitable, because if the user types in an ad hoc IP address, it may fail to resolve it even though, since it's an IP address, you have everything you need to make a connection. GetHostByName is exactly the function you need in this case, but Microsoft have chosen to deprecate it. Given the deprecation, the idiom is going to be to replicate the "try to parse first" approach that @Faisai Mansoor showed in the decompiled GetHostByName function:

// Microsoft's internal code for GetHostByName:
if (IPAddress.TryParse(hostName, out address))
  return Dns.GetUnresolveAnswer(address);
else
  return Dns.InternalGetHostByName(hostName, false);

This uses internal implementation details of the Dns class, but the spirit of it is easy to replicate in your own code, e.g.:

if (!IPAddress.TryParse(userInput, out var addressToWhichToConnect))
  addressToWhichToConnect = Dns.GetHostEntry(userInput).AddressList.First();
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top