【问题标题】:Can't parse domain into IP in C#?无法在 C# 中将域解析为 IP?
【发布时间】:2011-09-23 20:07:16
【问题描述】:

我有这个代码:

IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(txtBoxIP.Text), MainForm.port);

例如,当我在 txtBoxIP (192.168.1.2) 中有一个 IP 时,它的效果很好。

但是如果我想放一个DNS呢?就像我说的(my.selfip.com)我得到了:

System.FormatException: An invalid IP address was specified.
at System.Net.IPAddress.InternalParse(String ipString, Boolean tryParse)

如何让它同时支持 IP 和 DNS?

【问题讨论】:

  • 我删除了 parsing 标签,因为将主机名转换为 IP 称为“地址解析”而不是“解析”。

标签: c# .net dns ip


【解决方案1】:
IPAddress ipAddress;
if (!IPAddress.TryParse (txtBoxIP.Text, out ipAddress))
   ipAddress = Dns.GetHostEntry (txtBoxIP.Text).AddressList[0];
serverEndPoint = new IPEndPoint(ipAddress, MainForm.port)

不要忘记错误处理。

【讨论】:

  • 是的,TryParse 好多了:-)
【解决方案2】:

DNS 到 IP 列表

IPHostEntry nameToIpAddress;
nameToIpAddress = Dns.GetHostEntry("HostName");
foreach (IPAddress address in nameToIpAddress.AddressList)
    Console.WriteLine(address.ToString());

然后您可以使用地址列表中的 IP。

Here 是一篇很棒的文章

【讨论】:

  • 是的,但是我怎样才能同时支持输入,DNS 和 IP 呢?
  • 如果输入不是 IP 地址,您首先将其转换为 IP 地址。然后像以前一样继续。
  • 您使用 DNS 名称解析到的 IPAddress(es) [其中之一]。使用 IPAddress.TryParse()。如果成功,您将获得一个 IP 地址。如果不是,则名称是 DNS 名称(或应该是),那么您需要通过 DNS.GetHostEntry() 解析名称。
【解决方案3】:
var input = txtBoxIP.Text;
IPAddress ip;

// TryParse returns true when IP is parsed successfully
if (!IPAddress.TryParse (input, out ip))
    // in case user input is not an IP, assume it's a hostname
    ip = Dns.GetHostEntry (input).AddressList [0]; // you may use the first one

// note that you'll also want to handle input errors
// such as invalid strings that are neither IPs nor valid domains,
// as well as hosts that couldn't be resolved

var serverEndPoint = new IPEndPoint (ip, MainForm.port);

【讨论】:

    【解决方案4】:

    DNS 名称不是 IP 地址。查看Dns.GetHostEntry() 进行DNS 解析。

    编辑添加:这是我所做的:

    public static IPEndPoint CreateEndpoint( string hostNameOrAddress , int port )
    {
      IPAddress addr    ;
      bool      gotAddr = IPAddress.TryParse( hostNameOrAddress , out addr ) ;
    
      if ( !gotAddr )
      {
        IPHostEntry dnsInfo = Dns.GetHostEntry( hostNameOrAddress ) ;
    
        addr = dnsInfo.AddressList.First() ;
    
      }
    
      IPEndPoint instance = new IPEndPoint( addr , port ) ;
      return instance ;
    }
    

    【讨论】:

      【解决方案5】:

      您必须自己查找主机名的 IP:

      string addrText = "www.example.com";
      IPAddress[] addresslist = Dns.GetHostAddresses(addrText);
      
      foreach (IPAddress theaddress in addresslist)
      {
         Console.WriteLine(theaddress.ToString());
      }
      

      编辑

      要区分两者之间的区别(顺便说一句,这使用了 C# 的一些功能,可能在 3.5 及更高版本中):

      bool isDomain = false;
      foreach(char c in addrText.ToCharArray())
      {
         if (char.IsLetter(c)){
           isDomain = true;
           break;
      }
      
      if (isDomain)
         // lookup IP here
      else
         // parse IP here
      

      【讨论】:

      • 是的,但我怎样才能同时支持输入,DNS 和 IP?
      • 我认为这与 ipv6 地址有问题,因为它们的字符串表示可以包含字母。
      【解决方案6】:

      注意:不,这不是似曾相识,这个答案与我在另一个重复问题上提供的完全相同......我想让这个问题的作者了解另一个问题,所以最好的方法是我'我们发现是在此处再次添加它,因为 Stack Overflow 上不赞成链接到其他答案。

      我有一个非常简洁的扩展方法!

      我考虑到 IPV6 可能会作为 DNS 类返回的地址列表中的第一个地址返回,并允许您对结果“偏爱”IPV6 或 IPV4。这是完整记录的类(为简洁起见,仅使用本案例的相关方法):

      using System;
      using System.Linq;
      using System.Net;
      using System.Net.Sockets;
      
      /// <summary>
      /// Basic helper methods around networking objects (IPAddress, IpEndPoint, Socket, etc.)
      /// </summary>
      public static class NetworkingExtensions
      {
          /// <summary>
          /// Converts a string representing a host name or address to its <see cref="IPAddress"/> representation, 
          /// optionally opting to return a IpV6 address (defaults to IpV4)
          /// </summary>
          /// <param name="hostNameOrAddress">Host name or address to convert into an <see cref="IPAddress"/></param>
          /// <param name="favorIpV6">When <code>true</code> will return an IpV6 address whenever available, otherwise 
          /// returns an IpV4 address instead.</param>
          /// <returns>The <see cref="IPAddress"/> represented by <paramref name="hostNameOrAddress"/> in either IpV4 or
          /// IpV6 (when available) format depending on <paramref name="favorIpV6"/></returns>
          public static IPAddress ToIPAddress(this string hostNameOrAddress, bool favorIpV6=false)
          {
              var favoredFamily = favorIpV6 ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork;
              var addrs = Dns.GetHostAddresses(hostNameOrAddress);
              return addrs.FirstOrDefault(addr => addr.AddressFamily == favoredFamily)
                     ??
                     addrs.FirstOrDefault();
          }
      }
      

      别忘了把这个类放在命名空间中! :-)

      现在你可以简单地这样做了:

      var server = "http://simpax.com.br".ToIPAddress();
      var blog = "http://simpax.codax.com.br".ToIPAddress();
      var google = "google.com.br".ToIPAddress();
      var ipv6Google = "google.com.br".ToIPAddress(true); // if available will be an IPV6
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-05
        • 1970-01-01
        • 2022-11-15
        • 1970-01-01
        • 2023-02-22
        • 2020-03-01
        • 2021-03-24
        • 2013-01-29
        相关资源
        最近更新 更多