Как получить * интернет * IP? - PullRequest
15 голосов
/ 05 февраля 2009

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

Ответы [ 15 ]

13 голосов
/ 05 февраля 2009

Попробуйте это:

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

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

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

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

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

8 голосов
/ 18 ноября 2009

Я предлагаю этот простой код, поскольку 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;
}
6 голосов
/ 07 декабря 2009

Это моя попытка получить 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;
}
2 голосов
/ 05 февраля 2009

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

2 голосов
/ 05 февраля 2009

Хакерский способ - выбрать и почистить один из множества сайтов типа «Что такое мой IP».

1 голос
/ 05 февраля 2009

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

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());
            }
        }
1 голос
/ 05 февраля 2009

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

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

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

0 голосов
/ 03 февраля 2012

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

   /* 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()); 
    }
0 голосов
/ 11 декабря 2009

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