Как получить * интернет * IP?

Представьте себе ситуацию, у меня есть ПК с двумя Lan-картами, один подключен к интернету, другой подключен к локальной сети, как я могу определить IP-адрес, который подключен к интернету с помощью С#?

Ответы

Ответ 1

Попробуйте следующее:

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(), чтобы показать, как использовать другие методы.
  • Обновлено для catch FormatException, если getInternetGateway() не удалось проанализировать IP-адрес шлюза. (Это может произойти, если маршрутизатор шлюза настроен таким образом, что он не отвечает на traceroute запросы.)
  • Процитированный комментарий Брайана Расмуссена.
  • Обновлен для использования IP для www.example.com, так что он работает, даже когда DNS-сервер отключен.

Ответ 2

Интернет-соединение должно быть в той же IP-сети, что и шлюз по умолчанию.

Там действительно нет надежного способа сказать по IP-адресу, если вы можете добраться до "Интернета" или нет. В основном вы можете общаться со своей собственной IP-сетью. Все остальное должно пройти через шлюз. Поэтому, если вы не видите шлюз, вы ограничены локальной сетью IP.

Однако шлюз зависит от других шлюзов, поэтому, даже если вы можете получить доступ к шлюзу, вы не сможете добраться до какой-либо другой сети. Это может быть обусловлено, например, фильтрации или отсутствия маршрутов в нужные сети.

На самом деле, нет смысла говорить об Интернете в этом смысле, так как вы, вероятно, никогда не сможете достичь всего Интернета в любой момент. Поэтому выясните, что вам нужно, чтобы достичь и проверить подключение к этой сети.

Ответ 3

Я предлагаю этот простой код, так как 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;
}

Ответ 4

Это моя попытка получить адрес 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;
}

Ответ 5

Хакерным способом является извлечение и очистка одного из многих сайтов типа "Что такое мой IP".

Ответ 6

Не 100% точно (некоторые интернет-провайдеры не предоставляют вам общедоступные IP-адреса), но вы можете проверить, находится ли IP-адрес в одном из диапазонов, зарезервированных для частных адресов. См. http://en.wikipedia.org/wiki/Classful_network

Ответ 7

Вот статья, которая может быть полезна:

Как получить "Сетевые интерфейсы" на С#

Следующий код используется для извлечения "сетевые интерфейсы" на С#. Вы могут распознавать "сетевые интерфейсы", как "Сетевые и удаленные подключения": Вы можете получить к ним доступ, используя "Пуск > Настройкa > Сетевые и удаленные подключения". С# не предоставляет простой способ получить этот список.

Ответ 8

Я нашел решение:

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

Ответ 9

Я уже искал это, я нашел его в этом проекте codeplex http://www.codeplex.com/xedus. Это не работающая бесплатная программа P2P, но есть класс, который использует правильный API для получения карты LAN-карт, имеющей интернет-ip

Ответ 10

Для быстрого взлома (который, разумеется, сломается сложными конфигурациями локальной сети или IPv6), получите список всех IP-адресов, имеющихся у текущего компьютера, и разделите все IP: s, которые соответствуют любому из следующих:

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

Ответ 11

Используйте tracert. Первый прыжок всегда должен находиться в той же подсети, что и ваш сетевой сетевой адаптер.

из командной строки.

tracert google.com

первая строка - 10.0.0.254, а мой nic имеет ip 10.0.2.48. Затем это простое упражнение по анализу вывода из tracert.

Ответ 12

Альтернативным решением (возможно, более точным) является использование команды 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];
        }
    }
}

Ответ 13

в том же направлении, что и Лукас Шалкаускас, мой друг, и я написал этот код:

   /* 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()); 
    }

Ответ 14

Попробуйте выполнить ping на www.google.com на обоих интерфейсах.

Ответ 15

Вы можете просто прочитать http://myip.dnsomatic.com/

Это надежная служба OpenDNS, и я использую ее для получения внешнего IP-адреса все время.