如何获得*互联网* IP?

时间:2009-02-05 11:02:49

标签: c# networking

想象一下这种情况,我有两台局域网的PC,一台连接到互联网另一台连接到本地网络,如何通过C#检测连接到互联网的IP?

15 个答案:

答案 0 :(得分:13)

试试这个:

static IPAddress getInternetIPAddress()
{
    try
    {
        IPAddress[] addresses = Dns.GetHostAddresses(Dns.GetHostName());
        IPAddress gateway = IPAddress.Parse(getInternetGateway());
        return findMatch(addresses, gateway);
    }
    catch (FormatException e) { return null; }
}

static string getInternetGateway()
{
    using (Process tracert = new Process())
    {
        ProcessStartInfo startInfo = tracert.StartInfo;
        startInfo.FileName = "tracert.exe";
        startInfo.Arguments = "-h 1 208.77.188.166"; // www.example.com
        startInfo.UseShellExecute = false;
        startInfo.RedirectStandardOutput = true;
        tracert.Start();

        using (StreamReader reader = tracert.StandardOutput)
        {
            string line = "";
            for (int i = 0; i < 9; ++i)
                line = reader.ReadLine();
            line = line.Trim();
            return line.Substring(line.LastIndexOf(' ') + 1);
        }
    }
}

static IPAddress findMatch(IPAddress[] addresses, IPAddress gateway)
{
    byte[] gatewayBytes = gateway.GetAddressBytes();
    foreach (IPAddress ip in addresses)
    {
        byte[] ipBytes = ip.GetAddressBytes();
        if (ipBytes[0] == gatewayBytes[0]
            && ipBytes[1] == gatewayBytes[1]
            && ipBytes[2] == gatewayBytes[2])
        {
            return ip;
        }
    }
    return null;
}

请注意,findMatch()的此实现依赖于C类匹配。如果您想支持B类匹配,只需省略对ipBytes[2] == gatewayBytes[2]

的检查

修改历史记录:

  • 已更新以使用www.example.com
  • 已更新为包含getInternetIPAddress(),以说明如何使用其他方法。
  • 如果FormatException无法解析网关IP,则更新以捕获getInternetGateway()。 (如果配置网关路由器使其不响应traceroute请求,则会发生这种情况。)
  • 引用Brian Rasmussen的评论。
  • 已更新为使用www.example.com的IP,因此即使DNS服务器关闭也能正常工作。

答案 1 :(得分:9)

互联网连接必须与默认网关位于同一IP网络上。

如果你能够到达“互联网”,那么无法从IP地址告诉我。基本上,您可以与自己的IP网络进行通信。其他一切都必须通过网关。因此,如果您看不到网关,则仅限于本地IP网络。

然而,网关依赖于其他网关,因此即使您可以访问网关,也可能无法访问其他网络。这可能是由于例如过滤或缺少到所需网络的路由。

实际上,从这个意义上谈论互联网是没有意义的,因为在任何特定时刻你可能永远无法访问整个互联网。因此,找出您需要能够访问和验证该网络的连接。

答案 2 :(得分:8)

我建议使用这个简单的代码,因为tracert并不总是有效,而且whatsmyip.com不是专门为此目的设计的:

private void GetIP()
{
    WebClient wc = new WebClient();
    string strIP = wc.DownloadString("http://checkip.dyndns.org");
    strIP = (new Regex(@"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")).Match(strIP).Value;
    wc.Dispose();
    return strIP;
}

答案 3 :(得分:6)

这是我尝试获取默认IPv4地址而不必求助于DNS或外部进程调用ipconfig和route等命令。希望下一版本的.Net能够访问Windows路由表。

public static IPAddress GetDefaultIPv4Address()
{
    var adapters = from adapter in NetworkInterface.GetAllNetworkInterfaces()
                   where adapter.OperationalStatus == OperationalStatus.Up &&
                    adapter.Supports(NetworkInterfaceComponent.IPv4)
                    && adapter.GetIPProperties().GatewayAddresses.Count > 0 &&
                    adapter.GetIPProperties().GatewayAddresses[0].Address.ToString() != "0.0.0.0"
                   select adapter;

     if (adapters.Count() > 1)
     {
          throw new ApplicationException("The default IPv4 address could not be determined as there are two interfaces with gateways.");
     }
     else
     {
         UnicastIPAddressInformationCollection localIPs = adapters.First().GetIPProperties().UnicastAddresses;
         foreach (UnicastIPAddressInformation localIP in localIPs)
         {
            if (localIP.Address.AddressFamily == AddressFamily.InterNetwork &&
                !localIP.Address.ToString().StartsWith(LINK_LOCAL_BLOCK_PREFIX) &&
                !IPAddress.IsLoopback(localIP.Address))
            {
                return localIP.Address;
            }
        }
    }

    return null;
}

答案 4 :(得分:2)

一种愚蠢的方式是获取并抓取许多“我的IP是什么”类型网站中的一个。

答案 5 :(得分:2)

不是100%准确(某些ISP不提供公共IP地址),但您可以检查IP地址是否在为私有地址保留的范围之一。见http://en.wikipedia.org/wiki/Classful_network

答案 6 :(得分:1)

以下是一篇可能有用的文章:

How to Retrieve "Network Interfaces" in C#

  

以下代码用于检索   C#中的“网络接口”。您   可能会认出“网络接口”   作为“网络和拨号连接”:   您可以使用以下方式访问它们   “开始&gt;设置&gt;网络和拨号连接”。   C#没有提供   检索此列表的简单方法。

答案 7 :(得分:1)

我找到了解决方案:

IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
Console.WriteLine(ipProperties.HostName);

        foreach (NetworkInterface networkCard in NetworkInterface.GetAllNetworkInterfaces())
        {
            foreach (GatewayIPAddressInformation gatewayAddr in networkCard.GetIPProperties().GatewayAddresses)
            {
                Console.WriteLine("Information: ");
                Console.WriteLine("Interface type: {0}", networkCard.NetworkInterfaceType.ToString());
                Console.WriteLine("Name: {0}", networkCard.Name);
                Console.WriteLine("Id: {0}", networkCard.Id);
                Console.WriteLine("Description: {0}", networkCard.Description);
                Console.WriteLine("Gateway address: {0}", gatewayAddr.Address.ToString());
                Console.WriteLine("IP: {0}", System.Net.Dns.GetHostByName(System.Net.Dns.GetHostName()).AddressList[0].ToString());
                Console.WriteLine("Speed: {0}", networkCard.Speed);
                Console.WriteLine("MAC: {0}", networkCard.GetPhysicalAddress().ToString());
            }
        }

答案 8 :(得分:0)

我已经搜索过了,我在这个codeplex项目http://www.codeplex.com/xedus中找到了它。 它是一个无法工作的P2P免费软件,但是有一个类使用正确的API来获取lan卡巫婆有互联网IP

答案 9 :(得分:0)

对于快速入侵(通过精心设计的LAN配置或IPv6肯定会破坏),获取当前计算机所有IP的列表,并删除所有符合以下任何内容的IP:

10.*
127.*          // <- Kudos to Brian for spotting the mistake
172.[16-31].*
192.168.*

答案 10 :(得分:0)

使用tracert。第一跳应始终与您的Internet NIC位于同一子网上。

来自命令提示符的示例。

tracert google.com

第一行是10.0.0.254,我的网站的IP是10.0.2.48。然后,这是一个解析tracert输出的简单练习。

答案 11 :(得分:0)

另一种解决方案(可能更准确)是使用Windows route命令。以下是一些适用于Windows Vista的代码:

static string getInternetConnectionIP()
{
    using (Process route = new Process())
    {
        ProcessStartInfo startInfo = route.StartInfo;
        startInfo.FileName = "route.exe";
        startInfo.Arguments = "print 0.0.0.0";
        startInfo.UseShellExecute = false;
        startInfo.RedirectStandardOutput = true;
        route.Start();

        using (StreamReader reader = route.StandardOutput)
        {
            string line;
            do
            {
                line = reader.ReadLine();
            } while (!line.StartsWith("          0.0.0.0"));

            // the interface is the fourth entry in the line
            return line.Split(new char[] { ' ' },
                              StringSplitOptions.RemoveEmptyEntries)[3];
        }
    }
}

答案 12 :(得分:0)

和我的朋友LukasŠalkauskas一样,我写了这段代码:

   /* digged, built and (here and there) copied "as is" from web, without paying attention to style.
    Please, do not shot us for this. 
   */
public static void DisplayIPAddresses() 
    { 

        Console.WriteLine("\r\n****************************"); 
        Console.WriteLine("     IPAddresses"); 
        Console.WriteLine("****************************"); 


        StringBuilder sb = new StringBuilder(); 
        // Get a list of all network interfaces (usually one per network card, dialup, and VPN connection)      
        NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces(); 

        foreach (NetworkInterface network in networkInterfaces) 
        { 

            if (network.OperationalStatus == OperationalStatus.Up ) 
            { 
                if (network.NetworkInterfaceType == NetworkInterfaceType.Tunnel) continue; 
                if (network.NetworkInterfaceType == NetworkInterfaceType.Tunnel) continue; 
                //GatewayIPAddressInformationCollection GATE = network.GetIPProperties().GatewayAddresses; 
                // Read the IP configuration for each network    

                IPInterfaceProperties properties = network.GetIPProperties(); 
                //discard those who do not have a real gateaway  
                if (properties.GatewayAddresses.Count > 0) 
                { 
                    bool good = false; 
                    foreach  (GatewayIPAddressInformation gInfo in properties.GatewayAddresses) 
                    { 
                        //not a true gateaway (VmWare Lan) 
                        if (!gInfo.Address.ToString().Equals("0.0.0.0")) 
                        { 
                            sb.AppendLine(" GATEAWAY "+ gInfo.Address.ToString()); 
                            good = true; 
                            break; 
                        } 
                    } 
                    if (!good) 
                    { 
                        continue; 
                    } 
                } 
                else { 
                    continue; 
                } 
                // Each network interface may have multiple IP addresses        
                foreach (IPAddressInformation address in properties.UnicastAddresses) 
                { 
                    // We're only interested in IPv4 addresses for now        
                    if (address.Address.AddressFamily != AddressFamily.InterNetwork) continue; 

                    // Ignore loopback addresses (e.g., 127.0.0.1)     
                    if (IPAddress.IsLoopback(address.Address)) continue; 

                    if (!address.IsDnsEligible) continue; 
                    if (address.IsTransient) continue;  

                    sb.AppendLine(address.Address.ToString() + " (" + network.Name + ") nType:" + network.NetworkInterfaceType.ToString()     ); 
                } 
            } 
        } 
        Console.WriteLine(sb.ToString()); 
    }

答案 13 :(得分:-1)

尝试在两个界面上ping www.google.com。

答案 14 :(得分:-1)

您只需阅读http://myip.dnsomatic.com/

即可

这是OpenDNS提供的可靠服务,我一直用它来获取外部IP。