Jak uzyskać adres IP serwera, na którym działa moja aplikacja C #?

365

Korzystam z serwera i chcę wyświetlić własny adres IP.

Jaka jest składnia na uzyskanie własnego (w miarę możliwości, zewnętrznego) adresu IP komputera?

Ktoś napisał następujący kod.

IPHostEntry host;
string localIP = "?";
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
    if (ip.AddressFamily.ToString() == "InterNetwork")
    {
        localIP = ip.ToString();
    }
}
return localIP;

Jednak ogólnie nie ufam autorowi i nie rozumiem tego kodu. Czy jest na to lepszy sposób?

Nefzen
źródło
1
Jeśli chodzi o zewnętrzny adres IP, nie sądzę, aby istniało lokalne podejście do jego odzyskiwania. Host lokalny może znajdować się za routerem NAT, który tłumaczy adresy sieci lokalnej na adresy publiczne. Czy istnieje (lokalny) sposób sprawdzenia, czy tak jest? Nie znam żadnego ...
Thiago Arrais
Próbka używa DNS, aby uzyskać adres IP, miałem doświadczenie z DNS posiadającym błędne informacje. W takim przypadku próbka może odpowiedzieć nieprawidłowymi informacjami.
leiflundgren
@leiflundgren Miałem również doświadczenie z nieprawidłowymi informacjami o systemie DNS. Moja odpowiedź opisuje, w jaki sposób uzyskałem adres IP, którego potrzebowałem, nie polegając na DNS, kiedy miałem do czynienia z tą sytuacją.
Dr Wily's Apprentice,
13
Za pomocą LINQ:Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(o => o.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).First().ToString()
Luis Perez
2
Jest to typowa sytuacja, w której użytkownicy o zupełnie różnych potrzebach mają tendencję do zadawania tego samego pytania. Niektóre osoby chcą wiedzieć, w jaki sposób można uzyskać dostęp do ich komputera z sieci publicznej. Odpowiedź kanoniczna to STUN , choć wiele odpowiedzi zawiera hacki zależne od losowych stron trzecich. Niektóre osoby chcą po prostu znać swoje adresy IP w sieci lokalnej. Dobre odpowiedzi w tym przypadku wspominają o NetworkInterface.GetAllNetworkInterfaces Method .
Stéphane Gourichon

Odpowiedzi:

237

Nie, to prawie najlepszy sposób na zrobienie tego. Ponieważ maszyna może mieć kilka adresów IP, musisz iterować ich zbiór, aby znaleźć właściwy.

Edycja: Jedyne, co chciałbym zmienić, to zmienić to:

if (ip.AddressFamily.ToString() == "InterNetwork")

do tego:

if (ip.AddressFamily == AddressFamily.InterNetwork)

Nie ma potrzeby ToStringwyliczania do porównania.

Andrew Hare
źródło
3
Chcę zewnętrznego adresu IP, jeśli to możliwe. Przypuszczam, że nie będzie to możliwe, jeśli będę za NAT.
Nefzen
3
Nie, twoje urządzenie będzie znało tylko swój adres NAT.
Andrew Hare,
1
Jestem prawie pewien, że będziesz musiał skontaktować się z zewnętrznym serwerem w celu uzyskania adresu zewnętrznego.
Thiago Arrais,
29
Sugerowałbym również breakstwierdzenie po tym, jak zostanie wykryte IP, aby uniknąć niepotrzebnego iterowania przez kolekcję (w tym przypadku wątpię, aby wpływ na wydajność kiedykolwiek miał znaczenie, ale lubię podkreślać ogólnie dobre nawyki kodowania)
Eric J.
7
Pamiętaj, że może się to nie powieść, gdy komputer ma wiele portów „InterNetwork” (w moim przypadku: karta Ethernet i port maszyny wirtualnej). Obecny kod da ci ostatni adres IP na liście.
Christian Studer
168

Jedynym sposobem na poznanie twojego publicznego adresu IP jest poproszenie kogoś innego, aby ci powiedział; ten kod może ci pomóc:

public string GetPublicIP()
{
    String direction = "";
    WebRequest request = WebRequest.Create("http://checkip.dyndns.org/");
    using (WebResponse response = request.GetResponse())
    using (StreamReader stream = new StreamReader(response.GetResponseStream()))
    {
        direction = stream.ReadToEnd();
    }

    //Search for the ip in the html
    int first = direction.IndexOf("Address: ") + 9;
    int last = direction.LastIndexOf("</body>");
    direction = direction.Substring(first, last - first);

    return direction;
}
ezgar
źródło
20
Czy wiesz, że Twój przykładowy kod został wymieniony w pytaniu 13 Dwadzieścia pytań w języku C # wyjaśnionych w Microsoft Academy? Prezenter przeprasza za kradzież twojego kodu. Od 8:30 minut. Zobacz to . :)
Erwin Rooijakkers
4
Niestety link nie działa.
Barry Guvenkaya
Nowy link na wypadek, gdyby ktokolwiek chciał go zobaczyć
Kimmax,
1
Proszę użyć linku ipof.in/txt, aby uzyskać adres IP bezpośrednio bez całego kodu parsowania HTML
vivekv 28.09.16
82

Środek czyszczący i wszystko w jednym: D

//This returns the first IP4 address or null
return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
Mohammed A. Fadil
źródło
3
Problemy z tym kodem: * Zakłada, że ​​komputer ma tylko jeden adres IP. Wiele ma wiele. * Uwzględnia tylko adresy IPV4. Dodaj InterNetworkV6, aby uwzględnić IPV6.
Robert Bratton
1
@RobertBratton, dziękuję za powtórkę. Problem nie zakładał wielu adresów IP ani IPV6, z niewielkimi modyfikacjami tego kodu może obsługiwać określone różne problemy.
Mohammed A. Fadil
50

Jeśli nie możesz polegać na uzyskaniu adresu IP z serwera DNS (co mi się przydarzyło), możesz zastosować następujące podejście:

Przestrzeń nazw System.Net.NetworkInformation zawiera klasę NetworkInterface , która ma statyczną metodę GetAllNetworkInterfaces .

Ta metoda zwróci wszystkie „interfejsy sieciowe” na twoim komputerze i ogólnie jest ich całkiem sporo, nawet jeśli masz tylko kartę bezprzewodową i / lub sprzęt karty Ethernet zainstalowany na twoim komputerze. Wszystkie te interfejsy sieciowe mają prawidłowe adresy IP dla twojego komputera lokalnego, chociaż prawdopodobnie potrzebujesz tylko jednego.

Jeśli szukasz jednego adresu IP, musisz przefiltrować listę, aż znajdziesz właściwy adres. Prawdopodobnie będziesz musiał przeprowadzić eksperymenty, ale udało mi się osiągnąć następujące podejście:

  • Odfiltruj wszelkie nieaktywne interfejsy sieciowe, sprawdzając, czy są OperationalStatus == OperationalStatus.Up. Wyklucza to fizyczny adapter Ethernet, na przykład, jeśli nie masz podłączonego kabla sieciowego.

Dla każdego NetworkInterface można uzyskać obiekt IPInterfaceProperties przy użyciu metody GetIPProperties , a z obiektu IPInterfaceProperties można uzyskać dostęp do właściwości UnicastAddresses, aby uzyskać listę obiektów UnicastIPAddressInformation .

  • Odfiltruj niepreferencyjne adresy emisji pojedynczej, sprawdzając DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred
  • Odfiltruj adresy „wirtualne”, sprawdzając AddressPreferredLifetime != UInt32.MaxValue.

W tym momencie biorę adres pierwszego (jeśli w ogóle) adresu emisji pojedynczej, który pasuje do wszystkich tych filtrów.

EDYTOWAĆ:

[zmieniony kod 16 maja 2018 r., aby uwzględnić warunki wymienione w powyższym tekście dla stanu wykrywania duplikatów adresów i preferowanego czasu życia]

Poniższy przykład pokazuje filtrowanie na podstawie statusu operacyjnego, rodziny adresów, z wyłączeniem adresu sprzężenia zwrotnego (127.0.0.1), stanu wykrywania duplikatów adresów i preferowanego czasu życia.

static IEnumerable<IPAddress> GetLocalIpAddresses()
{
    // Get the list of network interfaces for the local computer.
    var adapters = NetworkInterface.GetAllNetworkInterfaces();

    // Return the list of local IPv4 addresses excluding the local
    // host, disconnected, and virtual addresses.
    return (from adapter in adapters
            let properties = adapter.GetIPProperties()
            from address in properties.UnicastAddresses
            where adapter.OperationalStatus == OperationalStatus.Up &&
                  address.Address.AddressFamily == AddressFamily.InterNetwork &&
                  !address.Equals(IPAddress.Loopback) &&
                  address.DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred &&
                  address.AddressPreferredLifetime != UInt32.MaxValue
            select address.Address);
}
Dr Wily's Apprentice
źródło
2
W tym konkretnym przypadku PO chciał zobaczyć swój zewnętrzny adres IP, więc rozwiązanie DNS jest prawdopodobnie dobrym rozwiązaniem. Ale w przypadku iteracji lokalnych adresów IP jest to podejście, które zalecam.
Matt Davis,
3
Zgodzono się, że DNS to łatwiejszy sposób na uzyskanie adresu IP. Wspomniałem w mojej odpowiedzi, że takie podejście działa, gdy twój DNS jest zawodny. Użyłem tego w środowisku, w którym DNS był pomieszany, tak że jeśli przeniesiesz maszynę z jednego portu Ethernet do innego, DNS nadal zgłasza stary adres IP, więc był prawie bezużyteczny dla moich celów.
Dr Wily's Apprentice
Doceniam cały opis, ale ty też powinieneś zamieścić próbkę kodu.
Aidin
Wspaniale dzięki. Należy pamiętać, że po ostatniej aktualizacji systemu Windows, UnicastAddresses. Pierwsze założenie już nie obowiązuje. Teraz muszę sprawdzić wszystkie adresy UnicastAddress dla każdego adaptera z dalszym filtrowaniem przy użyciu AddressPreferredLifetime i DuplicateAddressDetectionStation (wspomniane w tekście powyżej)
user3085342
37
WebClient webClient = new WebClient();
string IP = webClient.DownloadString("http://myip.ozymo.com/");
James
źródło
ifconfig.me/ip już nie działa. Zamiast tego spróbuj api.ipify.org lub link w komentarzu Douga
Kenny83,
16
using System.Net;

string host = Dns.GetHostName();
IPHostEntry ip = Dns.GetHostEntry(host);
Console.WriteLine(ip.AddressList[0].ToString());

Właśnie przetestowałem to na moim komputerze i działa.

opedog
źródło
3
będzie uzyskać u lokalnego IP, a pytanie jest o zewnętrznym IP ieIp z których u przeglądać internet ..
Sangram Nandkhile
15

Jeśli chcesz uniknąć używania DNS:

List<IPAddress> ipList = new List<IPAddress>();
foreach (var netInterface in NetworkInterface.GetAllNetworkInterfaces())
{
    foreach (var address in netInterface.GetIPProperties().UnicastAddresses)
    {
        if (address.Address.AddressFamily == AddressFamily.InterNetwork)
        {
            Console.WriteLine("found IP " + address.Address.ToString());
            ipList.Add(address.Address);
        }
    }
}
reza
źródło
9

Nie polegaj cały czas na InterNetwork, ponieważ możesz mieć więcej niż jedno urządzenie, które również korzysta z IP4, co popsułoby wyniki w uzyskiwaniu twojego IP. Teraz, jeśli chcesz, możesz po prostu skopiować to i przejrzeć je lub zaktualizować do swojego uznania.

Najpierw dostaję adres routera (bramy) Jeśli wróci, że jestem podłączony do bramy (co oznacza, że ​​nie jestem podłączony bezpośrednio do modemu bezprzewodowo lub nie), to mamy adres bramy jako adres IP, w przeciwnym razie jesteśmy wskaźnikiem zerowym .

Następnie musimy uzyskać listę adresów IP komputera. To nie jest tak trudne, ponieważ routery (wszystkie routery) używają 4 bajtów (...). Pierwsze trzy są najważniejsze, ponieważ każdy podłączony do niego komputer będzie miał adres IP4 zgodny z pierwszymi trzema bajtami. Np .: 192.168.0.1 jest standardem dla domyślnego adresu IP routera, chyba że zostanie zmieniony przez administratora. „192.168.0” lub cokolwiek to może być, musimy dopasować. I to wszystko, co zrobiłem w funkcji IsAddressOfGateway. Powodem dopasowania długości jest to, że nie wszystkie adresy (tylko dla komputera) mają długość 4 bajtów. Jeśli wpiszesz netstat w cmd, przekonasz się, że to prawda. Więc masz to. Tak, potrzeba trochę więcej pracy, aby naprawdę dostać to, czego szukasz. Proces eliminacji. I na miłość boską nie znajduj adresu przez pingowanie, co zajmuje dużo czasu, ponieważ najpierw wysyłasz adres do pingowania, a następnie musi on wysłać wynik z powrotem. Nie, współpracuj bezpośrednio z klasami .Net, które zajmują się twoim środowiskiem systemowym, a uzyskasz odpowiedzi, których szukasz, gdy dotyczy to wyłącznie twojego komputera.

Teraz, jeśli jesteś podłączony bezpośrednio do modemu, proces jest prawie taki sam, ponieważ modem jest twoją bramą, ale podzadanie nie jest takie samo, ponieważ otrzymujesz informacje bezpośrednio z serwera DNS przez modem, a nie maskowane przez router obsługujący Internet dla ciebie, chociaż nadal możesz używać tego samego kodu, ponieważ ostatni bajt adresu IP przypisanego do modemu to 1. Więc jeśli adres IP wysłany z modemu, który się zmienia, to 111.111.111.1 ', otrzymasz 111.111.111. (Niektóre wartość bajtu). Pamiętaj, że musimy znaleźć informacje o bramie, ponieważ istnieje więcej urządzeń, które zajmują się łącznością z Internetem niż router i modem.

Teraz widzisz, dlaczego NIE zmieniasz pierwszych dwóch bajtów routera 192 i 168. Są one ściśle rozróżniane tylko dla routerów, a nie korzystania z Internetu, lub mielibyśmy poważny problem z protokołem IP i podwójnym pingowaniem powodującym awarię komputera. Obraz, że przypisany adres IP routera to 192.168.44.103 i użytkownik kliknął również witrynę z tym adresem IP. O MÓJ BOŻE! Twój komputer nie będzie wiedział, co pingować. Crash właśnie tam. Aby uniknąć tego problemu, przypisywane są tylko routery, a nie do korzystania z Internetu. Więc zostaw dwa pierwsze bajty routera w spokoju.

static IPAddress FindLanAddress()
{
    IPAddress gateway = FindGetGatewayAddress();
    if (gateway == null)
        return null;

    IPAddress[] pIPAddress = Dns.GetHostAddresses(Dns.GetHostName());

    foreach (IPAddress address in pIPAddress)            {
        if (IsAddressOfGateway(address, gateway))
                return address;
    return null;
}
static bool IsAddressOfGateway(IPAddress address, IPAddress gateway)
{
    if (address != null && gateway != null)
        return IsAddressOfGateway(address.GetAddressBytes(),gateway.GetAddressBytes());
    return false;
}
static bool IsAddressOfGateway(byte[] address, byte[] gateway)
{
    if (address != null && gateway != null)
    {
        int gwLen = gateway.Length;
        if (gwLen > 0)
        {
            if (address.Length == gateway.Length)
            {
                --gwLen;
                int counter = 0;
                for (int i = 0; i < gwLen; i++)
                {
                    if (address[i] == gateway[i])
                        ++counter;
                }
                return (counter == gwLen);
            }
        }
    }
    return false;

}
static IPAddress FindGetGatewayAddress()
{
    IPGlobalProperties ipGlobProps = IPGlobalProperties.GetIPGlobalProperties();

    foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
    {
        IPInterfaceProperties ipInfProps = ni.GetIPProperties();
        foreach (GatewayIPAddressInformation gi in ipInfProps.GatewayAddresses)
            return gi.Address;
    }
    return null;
}
bvrwoo_3376
źródło
1
To nie ma sensu: foreach (GatewayIPAddressInformation gi w ipInfProps.GatewayAddresses) zwraca gi.Address;
Edwin Evans
3
Nie ma gwarancji, że „każdy komputer podłączony do bramy będzie miał adres IP4 zgodny z pierwszymi trzema bajtami”. Zależy to od maski podsieci, która może zawierać różne kombinacje bitów. Co więcej, bajtami początkowymi nie musi być „192.168”, jak opisano tutaj . Ten kod będzie działał tylko wtedy, gdy jest maska ​​podsieci 255.255.255.0, i zrobi to w dość skomplikowany sposób IMO.
Groo,
8

Pomyślałem tylko, że dodam własną, linijkę (chociaż jest już wiele innych przydatnych odpowiedzi).


string ipAddress = new WebClient().DownloadString("http://icanhazip.com");

bæltazor
źródło
4
Pamiętaj, że może to spowodować wyciek pamięci. WebClient nie jest odpowiednio usuwany. Zamiast tego użyj: using (var client = new WebClient ()) {return client.DownloadString (" icanhazip.com /"). Trim () ; }
FOO
4

Aby uzyskać bieżący publiczny adres IP, wystarczy utworzyć stronę ASPX z następującym wierszem zdarzenia ładowania strony:

Response.Write(HttpContext.Current.Request.UserHostAddress.ToString());
wykryć publiczny adres IP
źródło
4

Jeśli pracujesz w intranecie, będziesz mógł uzyskać adres IP komputera lokalnego, a jeśli nie, otrzymasz zewnętrzny adres IP za pomocą tego: Web:

//this will bring the IP for the current machine on browser
System.Web.HttpContext.Current.Request.UserHostAddress

Pulpit:

//This one will bring all local IPs for the desired namespace
IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
Guilherme Ferreira
źródło
3
namespace NKUtilities 
{
    using System;
    using System.Net;
    using System.Net.Sockets;

    public class DNSUtility
    {
        public static int Main(string [] args)
        {
            string strHostName = "";
            try {

                if(args.Length == 0)
                {
                    // Getting Ip address of local machine...
                    // First get the host name of local machine.
                    strHostName = Dns.GetHostName();
                    Console.WriteLine ("Local Machine's Host Name: " +  strHostName);
                }
                else
                {
                    // Otherwise, get the IP address of the host provided on the command line.
                    strHostName = args[0];
                }

                // Then using host name, get the IP address list..
                IPHostEntry ipEntry = Dns.GetHostEntry (strHostName);
                IPAddress [] addr = ipEntry.AddressList;

                for(int i = 0; i < addr.Length; i++)
                {
                    Console.WriteLine("IP Address {0}: {1} ", i, addr[i].ToString());
                }
                return 0;

            } 
            catch(SocketException se) 
            {
                Console.WriteLine("{0} ({1})", se.Message, strHostName);
                return -1;
            } 
            catch(Exception ex) 
            {
                Console.WriteLine("Error: {0}.", ex.Message);
                return -1;
            }
        }
    }
}

Spójrz tutaj po szczegóły.

Musisz pamiętać, że twój komputer może mieć więcej niż jeden adres IP (w rzeczywistości zawsze tak jest) - więc po co chcesz.

Mfloryan
źródło
2

Spróbuj tego:

 IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
 String MyIp = localIPs[0].ToString();
Maska
źródło
1
Zwraca to liczbę lokalnych adresów IP, z których jeden jest adresem IPv4, jednak trudno jest znaleźć właściwy adres na liście.
Contango,
1

Może na podstawie zewnętrznego adresu IP możesz rozważyć (jeśli jesteś w kontekście serwera WWW), używając tego

Request.ServerVariables["LOCAL_ADDR"];

Zadałem to samo pytanie, co ty i znalazłem w tym artykule o przepływie stosów.

To zadziałało dla mnie.

Juan Calero
źródło
1
namespace NKUtilities 
{
    using System;
    using System.Net;

    public class DNSUtility
    {
        public static int Main (string [] args)
        {

          String strHostName = new String ("");
          if (args.Length == 0)
          {
              // Getting Ip address of local machine...
              // First get the host name of local machine.
              strHostName = Dns.GetHostName ();
              Console.WriteLine ("Local Machine's Host Name: " +  strHostName);
          }
          else
          {
              strHostName = args[0];
          }

          // Then using host name, get the IP address list..
          IPHostEntry ipEntry = DNS.GetHostByName (strHostName);
          IPAddress [] addr = ipEntry.AddressList;

          for (int i = 0; i < addr.Length; i++)
          {
              Console.WriteLine ("IP Address {0}: {1} ", i, addr[i].ToString ());
          }
          return 0;
        }    
     }
}
naani
źródło
1
using System;
using System.Net;

namespace IPADDRESS
{
    class Program
    {
        static void Main(string[] args)
        {
            String strHostName = string.Empty;
            if (args.Length == 0)
            {                
                /* First get the host name of local machine.*/
                strHostName = Dns.GetHostName();
                Console.WriteLine("Local Machine's Host Name: " + strHostName);
            }
            else
            {
                strHostName = args[0];
            }
            /* Then using host name, get the IP address list..*/
            IPHostEntry ipEntry = Dns.GetHostByName(strHostName);
            IPAddress[] addr = ipEntry.AddressList;
            for (int i = 0; i < addr.Length; i++)
            {
                Console.WriteLine("IP Address {0}: {1} ", i, addr[i].ToString());
            }
            Console.ReadLine();
        }
    }
}
Sundram
źródło
1
return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);

Prosty pojedynczy wiersz kodu, który zwraca pierwszy wewnętrzny adres IPV4 lub zero, jeśli nie ma. Dodany jako komentarz powyżej, ale może być przydatny dla kogoś (niektóre powyższe rozwiązania zwrócą wiele adresów, które wymagają dalszego filtrowania).

Łatwo jest również zwrócić pętlę zwrotną zamiast wartości zerowej. Myślę, że z:

return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork) ?? new IPAddress( new byte[] {127, 0, 0, 1} );
Wolf5370
źródło
1
Jak o IPAddress.Loopback? :)
CodeTherapist
1

Aby znaleźć listę adresów IP skorzystałem z tego rozwiązania

public static IEnumerable<string> GetAddresses()
{
    var host = Dns.GetHostEntry(Dns.GetHostName());
    return (from ip in host.AddressList where ip.AddressFamily == AddressFamily.lo select ip.ToString()).ToList();
}

Ale osobiście lubię poniższe rozwiązanie, aby uzyskać lokalny prawidłowy adres IP

public static IPAddress GetIPAddress(string hostName)
{
    Ping ping = new Ping();
    var replay = ping.Send(hostName);

    if (replay.Status == IPStatus.Success)
    {
        return replay.Address;
    }
    return null;
 }

public static void Main()
{
    Console.WriteLine("Local IP Address: " + GetIPAddress(Dns.GetHostName()));
    Console.WriteLine("Google IP:" + GetIPAddress("google.com");
    Console.ReadLine();
}
Ravi Shankar
źródło
1

Rozwiązanie LINQ:

Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork).Select(ip => ip.ToString()).FirstOrDefault() ?? ""
Serge
źródło
1

Oto jak to rozwiązałem. Wiem, że jeśli masz kilka fizycznych interfejsów, może nie wybrać dokładnie tego, czego chcesz.

private string FetchIP()
{
    //Get all IP registered
    List<string> IPList = new List<string>();
    IPHostEntry host;
    host = Dns.GetHostEntry(Dns.GetHostName());
    foreach (IPAddress ip in host.AddressList)
    {
        if (ip.AddressFamily == AddressFamily.InterNetwork)
        {
            IPList.Add(ip.ToString());
        }
    }

    //Find the first IP which is not only local
    foreach (string a in IPList)
    {
        Ping p = new Ping();
        string[] b = a.Split('.');
        string ip2 = b[0] + "." + b[1] + "." + b[2] + ".1";
        PingReply t = p.Send(ip2);
        p.Dispose();
        if (t.Status == IPStatus.Success && ip2 != a)
        {
            return a;
        }
    }
    return null;
}
Thomas Andreè Wang
źródło
1

Pytanie nie mówi: ASP.NET MVC, ale i tak zostawiam to tutaj:

Request.UserHostAddress
Barry Guvenkaya
źródło
1

Uzyskaj wszystkie adresy IP jako ciągi znaków, używając LINQ:

using System.Linq;
using System.Net.NetworkInformation;
using System.Net.Sockets;
...
string[] allIpAddresses = NetworkInterface.GetAllNetworkInterfaces()
    .SelectMany(c=>c.GetIPProperties().UnicastAddresses
        .Where(d=>d.Address.AddressFamily == AddressFamily.InterNetwork)
        .Select(d=>d.Address.ToString())
    ).ToArray();

ABY ODfiltrować PRYWATNE ...

Najpierw zdefiniuj metodę rozszerzenia IsPrivate():

public static class IPAddressExtensions
{
    // Collection of private CIDRs (IpAddress/Mask) 
    private static Tuple<int, int>[] _privateCidrs = new []{"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"}
        .Select(c=>Tuple.Create(BitConverter.ToInt32(IPAddress
                                    .Parse(c.Split('/')[0]).GetAddressBytes(), 0)
                              , IPAddress.HostToNetworkOrder(-1 << (32-int.Parse(c.Split('/')[1])))))
        .ToArray();
    public static bool IsPrivate(this IPAddress ipAddress)
    {
        int ip = BitConverter.ToInt32(ipAddress.GetAddressBytes(), 0);
        return _privateCidrs.Any(cidr=>(ip & cidr.Item2)==(cidr.Item1 & cidr.Item2));           
    }
}

... a następnie użyj go do odfiltrowania prywatnych adresów IP:

string[] publicIpAddresses = NetworkInterface.GetAllNetworkInterfaces()
    .SelectMany(c=>c.GetIPProperties().UnicastAddresses
        .Where(d=>d.Address.AddressFamily == AddressFamily.InterNetwork
            && !d.Address.IsPrivate() // Filter out private ones
        )
        .Select(d=>d.Address.ToString())
    ).ToArray();
Diego
źródło
1

Działa to dla mnie ... i powinno być szybsze w większości przypadków (jeśli nie wszystkich) niż odpytywanie serwera DNS. Dzięki App Drice Wily's Apprentice ( tutaj ).

// ************************************************************************
/// <summary>
/// Will search for the an active NetworkInterafce that has a Gateway, otherwise
/// it will fallback to try from the DNS which is not safe.
/// </summary>
/// <returns></returns>
public static NetworkInterface GetMainNetworkInterface()
{
    List<NetworkInterface> candidates = new List<NetworkInterface>();

    if (NetworkInterface.GetIsNetworkAvailable())
    {
        NetworkInterface[] NetworkInterfaces =
            NetworkInterface.GetAllNetworkInterfaces();

        foreach (
            NetworkInterface ni in NetworkInterfaces)
        {
            if (ni.OperationalStatus == OperationalStatus.Up)
                candidates.Add(ni);
        }
    }

    if (candidates.Count == 1)
    {
        return candidates[0];
    }

    // Accoring to our tech, the main NetworkInterface should have a Gateway 
    // and it should be the ony one with a gateway.
    if (candidates.Count > 1)
    {
        for (int n = candidates.Count - 1; n >= 0; n--)
        {
            if (candidates[n].GetIPProperties().GatewayAddresses.Count == 0)
            {
                candidates.RemoveAt(n);
            }
        }

        if (candidates.Count == 1)
        {
            return candidates[0];
        }
    }

    // Fallback to try by getting my ipAdress from the dns
    IPAddress myMainIpAdress = null;
    IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
    foreach (IPAddress ip in host.AddressList)
    {
        if (ip.AddressFamily == AddressFamily.InterNetwork) // Get the first IpV4
        {
            myMainIpAdress = ip;
            break;
        }
    }

    if (myMainIpAdress != null)
    {
        NetworkInterface[] NetworkInterfaces =
            NetworkInterface.GetAllNetworkInterfaces();

        foreach (NetworkInterface ni in NetworkInterfaces)
        {
            if (ni.OperationalStatus == OperationalStatus.Up)
            {
                IPInterfaceProperties props = ni.GetIPProperties();
                foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
                {
                    if (ai.Address.Equals(myMainIpAdress))
                    {
                        return ni;
                    }
                }
            }
        }
    }

    return null;
}

// ******************************************************************
/// <summary>
/// AddressFamily.InterNetwork = IPv4
/// Thanks to Dr. Wilys Apprentice at
/// http://stackoverflow.com/questions/1069103/how-to-get-the-ip-address-of-the-server-on-which-my-c-sharp-application-is-runni
/// using System.Net.NetworkInformation;
/// </summary>
/// <param name="mac"></param>
/// <param name="addressFamily">AddressFamily.InterNetwork = IPv4,  AddressFamily.InterNetworkV6 = IPv6</param>
/// <returns></returns>
public static IPAddress GetIpFromMac(PhysicalAddress mac, AddressFamily addressFamily = AddressFamily.InterNetwork)
{
    NetworkInterface[] NetworkInterfaces =
        NetworkInterface.GetAllNetworkInterfaces();

    foreach (NetworkInterface ni in NetworkInterfaces)
    {
        if (ni.GetPhysicalAddress().Equals(mac))
        {
            if (ni.OperationalStatus == OperationalStatus.Up)
            {
                IPInterfaceProperties props = ni.GetIPProperties();
                foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
                {
                    if (ai.DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred)
                    {
                        if (ai.Address.AddressFamily == addressFamily)
                        {
                            return ai.Address;
                        }
                    }
                }
            }
        }
    }

    return null;
}

// ******************************************************************
/// <summary>
/// Return the best guess of main ipAdress. To get it in the form aaa.bbb.ccc.ddd just call 
/// '?.ToString() ?? ""' on the result.
/// </summary>
/// <returns></returns>
public static IPAddress GetMyInternetIpAddress()
{
    NetworkInterface ni = GetMainNetworkInterface();
    IPAddress ipAddress = GetIpFromMac(ni.GetPhysicalAddress());
    if (ipAddress == null) // could it be possible ?
    {
        ipAddress = GetIpFromMac(ni.GetPhysicalAddress(), AddressFamily.InterNetworkV6);
    }

    return ipAddress;
}

// ******************************************************************

Jako odniesienie jest to pełny kod klasy, w którym go zdefiniowałem:

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

namespace TcpMonitor
{
    /*
        Usage:
                var cons = TcpHelper.GetAllTCPConnections();
                foreach (TcpHelper.MIB_TCPROW_OWNER_PID c in cons) ...
    */

    public class NetHelper
    {
        [DllImport("iphlpapi.dll", SetLastError = true)]
        static extern uint GetExtendedUdpTable(IntPtr pUdpTable, ref int dwOutBufLen, bool sort, int ipVersion, UDP_TABLE_CLASS tblClass, uint reserved = 0);

        public enum UDP_TABLE_CLASS
        {
            UDP_TABLE_BASIC,
            UDP_TABLE_OWNER_PID,
            UDP_TABLE_OWNER_MODULE
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_UDPTABLE_OWNER_PID
        {
            public uint dwNumEntries;
            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
            public MIB_UDPROW_OWNER_PID[] table;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_UDPROW_OWNER_PID
        {
            public uint localAddr;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] localPort;
            public uint owningPid;

            public uint ProcessId
            {
                get { return owningPid; }
            }

            public IPAddress LocalAddress
            {
                get { return new IPAddress(localAddr); }
            }

            public ushort LocalPort
            {
                get { return BitConverter.ToUInt16(localPort.Take(2).Reverse().ToArray(), 0); }
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_UDP6TABLE_OWNER_PID
        {
            public uint dwNumEntries;
            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
            public MIB_UDP6ROW_OWNER_PID[] table;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_UDP6ROW_OWNER_PID
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public byte[] localAddr;
            public uint localScopeId;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] localPort;
            public uint owningPid;
            public uint ProcessId
            {
                get { return owningPid; }
            }

            public IPAddress LocalAddress
            {
                get { return new IPAddress(localAddr, localScopeId); }
            }

            public ushort LocalPort
            {
                get { return BitConverter.ToUInt16(localPort.Take(2).Reverse().ToArray(), 0); }
            }
        }

        public static List<MIB_UDPROW_OWNER_PID> GetAllUDPConnections()
        {
            return GetUDPConnections<MIB_UDPROW_OWNER_PID, MIB_UDPTABLE_OWNER_PID> (AF_INET);
        }

        public static List<MIB_UDP6ROW_OWNER_PID> GetAllUDPv6Connections()
        {
            return GetUDPConnections<MIB_UDP6ROW_OWNER_PID, MIB_UDP6TABLE_OWNER_PID>(AF_INET6);
        }

        private static List<IPR> GetUDPConnections<IPR, IPT>(int ipVersion)//IPR = Row Type, IPT = Table Type
        {
            List<IPR> result = null;

            IPR[] tableRows = null;
            int buffSize = 0;

            var dwNumEntriesField = typeof(IPT).GetField("dwNumEntries");

            // how much memory do we need?
            uint ret = GetExtendedUdpTable(IntPtr.Zero, ref buffSize, true, ipVersion, UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID);
            IntPtr udpTablePtr = Marshal.AllocHGlobal(buffSize);

            try
            {
                ret = GetExtendedUdpTable(udpTablePtr, ref buffSize, true, ipVersion, UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID);
                if (ret != 0)
                    return new List<IPR>();

                // get the number of entries in the table
                IPT table = (IPT)Marshal.PtrToStructure(udpTablePtr, typeof(IPT));
                int rowStructSize = Marshal.SizeOf(typeof(IPR));
                uint numEntries = (uint)dwNumEntriesField.GetValue(table);

                // buffer we will be returning
                tableRows = new IPR[numEntries];

                IntPtr rowPtr = (IntPtr)((long)udpTablePtr + 4);
                for (int i = 0; i < numEntries; i++)
                {
                    IPR tcpRow = (IPR)Marshal.PtrToStructure(rowPtr, typeof(IPR));
                    tableRows[i] = tcpRow;
                    rowPtr = (IntPtr)((long)rowPtr + rowStructSize);   // next entry
                }
            }
            finally
            {
                result = tableRows?.ToList() ?? new List<IPR>();

                // Free the Memory
                Marshal.FreeHGlobal(udpTablePtr);
            }

            return result;
        }

        [DllImport("iphlpapi.dll", SetLastError = true)]
        static extern uint GetExtendedTcpTable(IntPtr pTcpTable, ref int dwOutBufLen, bool sort, int ipVersion, TCP_TABLE_CLASS tblClass, uint reserved = 0);



        public enum MIB_TCP_STATE
        {
            MIB_TCP_STATE_CLOSED = 1,
            MIB_TCP_STATE_LISTEN = 2,
            MIB_TCP_STATE_SYN_SENT = 3,
            MIB_TCP_STATE_SYN_RCVD = 4,
            MIB_TCP_STATE_ESTAB = 5,
            MIB_TCP_STATE_FIN_WAIT1 = 6,
            MIB_TCP_STATE_FIN_WAIT2 = 7,
            MIB_TCP_STATE_CLOSE_WAIT = 8,
            MIB_TCP_STATE_CLOSING = 9,
            MIB_TCP_STATE_LAST_ACK = 10,
            MIB_TCP_STATE_TIME_WAIT = 11,
            MIB_TCP_STATE_DELETE_TCB = 12
        }

        public enum TCP_TABLE_CLASS
        {
            TCP_TABLE_BASIC_LISTENER,
            TCP_TABLE_BASIC_CONNECTIONS,
            TCP_TABLE_BASIC_ALL,
            TCP_TABLE_OWNER_PID_LISTENER,
            TCP_TABLE_OWNER_PID_CONNECTIONS,
            TCP_TABLE_OWNER_PID_ALL,
            TCP_TABLE_OWNER_MODULE_LISTENER,
            TCP_TABLE_OWNER_MODULE_CONNECTIONS,
            TCP_TABLE_OWNER_MODULE_ALL
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_TCPTABLE_OWNER_PID
        {
            public uint dwNumEntries;
            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
            public MIB_TCPROW_OWNER_PID[] table;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_TCP6TABLE_OWNER_PID
        {
            public uint dwNumEntries;
            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
            public MIB_TCP6ROW_OWNER_PID[] table;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_TCPROW_OWNER_PID
        {
            public uint state;
            public uint localAddr;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] localPort;
            public uint remoteAddr;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] remotePort;
            public uint owningPid;

            public uint ProcessId
            {
                get { return owningPid; }
            }

            public IPAddress LocalAddress
            {
                get { return new IPAddress(localAddr); }
            }

            public ushort LocalPort
            {
                get
                {
                    return BitConverter.ToUInt16(new byte[2] { localPort[1], localPort[0] }, 0);
                }
            }

            public IPAddress RemoteAddress
            {
                get { return new IPAddress(remoteAddr); }
            }

            public ushort RemotePort
            {
                get
                {
                    return BitConverter.ToUInt16(new byte[2] { remotePort[1], remotePort[0] }, 0);
                }
            }

            public MIB_TCP_STATE State
            {
                get { return (MIB_TCP_STATE)state; }
            }
        }


        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_TCP6ROW_OWNER_PID
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public byte[] localAddr;
            public uint localScopeId;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] localPort;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public byte[] remoteAddr;
            public uint remoteScopeId;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] remotePort;
            public uint state;
            public uint owningPid;

            public uint ProcessId
            {
                get { return owningPid; }
            }

            public long LocalScopeId
            {
                get { return localScopeId; }
            }

            public IPAddress LocalAddress
            {
                get { return new IPAddress(localAddr, LocalScopeId); }
            }

            public ushort LocalPort
            {
                get { return BitConverter.ToUInt16(localPort.Take(2).Reverse().ToArray(), 0); }
            }

            public long RemoteScopeId
            {
                get { return remoteScopeId; }
            }

            public IPAddress RemoteAddress
            {
                get { return new IPAddress(remoteAddr, RemoteScopeId); }
            }

            public ushort RemotePort
            {
                get { return BitConverter.ToUInt16(remotePort.Take(2).Reverse().ToArray(), 0); }
            }

            public MIB_TCP_STATE State
            {
                get { return (MIB_TCP_STATE)state; }
            }
        }


        public const int AF_INET = 2;    // IP_v4 = System.Net.Sockets.AddressFamily.InterNetwork
        public const int AF_INET6 = 23;  // IP_v6 = System.Net.Sockets.AddressFamily.InterNetworkV6

        public static Task<List<MIB_TCPROW_OWNER_PID>> GetAllTCPConnectionsAsync()
        {
            return Task.Run(() => GetTCPConnections<MIB_TCPROW_OWNER_PID, MIB_TCPTABLE_OWNER_PID>(AF_INET));
        }

        public static List<MIB_TCPROW_OWNER_PID> GetAllTCPConnections()
        {
            return GetTCPConnections<MIB_TCPROW_OWNER_PID, MIB_TCPTABLE_OWNER_PID>(AF_INET);
        }

        public static Task<List<MIB_TCP6ROW_OWNER_PID>> GetAllTCPv6ConnectionsAsync()
        {
            return Task.Run(()=>GetTCPConnections<MIB_TCP6ROW_OWNER_PID, MIB_TCP6TABLE_OWNER_PID>(AF_INET6));
        }

        public static List<MIB_TCP6ROW_OWNER_PID> GetAllTCPv6Connections()
        {
            return GetTCPConnections<MIB_TCP6ROW_OWNER_PID, MIB_TCP6TABLE_OWNER_PID>(AF_INET6);
        }

        private static List<IPR> GetTCPConnections<IPR, IPT>(int ipVersion)//IPR = Row Type, IPT = Table Type
        {
            List<IPR> result = null;

            IPR[] tableRows = null;
            int buffSize = 0;

            var dwNumEntriesField = typeof(IPT).GetField("dwNumEntries");

            // how much memory do we need?
            uint ret = GetExtendedTcpTable(IntPtr.Zero, ref buffSize, true, ipVersion, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL);
            IntPtr tcpTablePtr = Marshal.AllocHGlobal(buffSize);

            try
            {
                ret = GetExtendedTcpTable(tcpTablePtr, ref buffSize, true, ipVersion, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL);
                if (ret != 0)
                    return new List<IPR>();

                // get the number of entries in the table
                IPT table = (IPT)Marshal.PtrToStructure(tcpTablePtr, typeof(IPT));
                int rowStructSize = Marshal.SizeOf(typeof(IPR));
                uint numEntries = (uint)dwNumEntriesField.GetValue(table);

                // buffer we will be returning
                tableRows = new IPR[numEntries];

                IntPtr rowPtr = (IntPtr)((long)tcpTablePtr + 4);
                for (int i = 0; i < numEntries; i++)
                {
                    IPR tcpRow = (IPR)Marshal.PtrToStructure(rowPtr, typeof(IPR));
                    tableRows[i] = tcpRow;
                    rowPtr = (IntPtr)((long)rowPtr + rowStructSize);   // next entry
                }
            }
            finally
            {
                result = tableRows?.ToList() ?? new List<IPR>();

                // Free the Memory
                Marshal.FreeHGlobal(tcpTablePtr);
            }

            return result;
        }

        public static string GetTcpStateName(MIB_TCP_STATE state)
        {
            switch (state)
            {
                case MIB_TCP_STATE.MIB_TCP_STATE_CLOSED:
                    return "Closed";
                case MIB_TCP_STATE.MIB_TCP_STATE_LISTEN:
                    return "Listen";
                case MIB_TCP_STATE.MIB_TCP_STATE_SYN_SENT:
                    return "SynSent";
                case MIB_TCP_STATE.MIB_TCP_STATE_SYN_RCVD:
                    return "SynReceived";
                case MIB_TCP_STATE.MIB_TCP_STATE_ESTAB:
                    return "Established";
                case MIB_TCP_STATE.MIB_TCP_STATE_FIN_WAIT1:
                    return "FinWait 1";
                case MIB_TCP_STATE.MIB_TCP_STATE_FIN_WAIT2:
                    return "FinWait 2";
                case MIB_TCP_STATE.MIB_TCP_STATE_CLOSE_WAIT:
                    return "CloseWait";
                case MIB_TCP_STATE.MIB_TCP_STATE_CLOSING:
                    return "Closing";
                case MIB_TCP_STATE.MIB_TCP_STATE_LAST_ACK:
                    return "LastAck";
                case MIB_TCP_STATE.MIB_TCP_STATE_TIME_WAIT:
                    return "TimeWait";
                case MIB_TCP_STATE.MIB_TCP_STATE_DELETE_TCB:
                    return "DeleteTCB";
                default:
                    return ((int)state).ToString();
            }
        }

        private static readonly ConcurrentDictionary<string, string> DicOfIpToHostName = new ConcurrentDictionary<string, string>();

        public const string UnknownHostName = "Unknown";

        // ******************************************************************
        public static string GetHostName(IPAddress ipAddress)
        {
            return GetHostName(ipAddress.ToString());
        }

        // ******************************************************************
        public static string GetHostName(string ipAddress)
        {
            string hostName = null;

            if (!DicOfIpToHostName.TryGetValue(ipAddress, out hostName))
            {
                try
                {
                    if (ipAddress == "0.0.0.0" || ipAddress == "::")
                    {
                        hostName = ipAddress;
                    }
                    else
                    {
                        hostName = Dns.GetHostEntry(ipAddress).HostName;
                    }
                }
                catch (Exception ex)
                {
                    Debug.Print(ex.ToString());
                    hostName = UnknownHostName;
                }

                DicOfIpToHostName[ipAddress] = hostName;
            }

            return hostName;
        }

        // ************************************************************************
        /// <summary>
        /// Will search for the an active NetworkInterafce that has a Gateway, otherwise
        /// it will fallback to try from the DNS which is not safe.
        /// </summary>
        /// <returns></returns>
        public static NetworkInterface GetMainNetworkInterface()
        {
            List<NetworkInterface> candidates = new List<NetworkInterface>();

            if (NetworkInterface.GetIsNetworkAvailable())
            {
                NetworkInterface[] NetworkInterfaces =
                    NetworkInterface.GetAllNetworkInterfaces();

                foreach (
                    NetworkInterface ni in NetworkInterfaces)
                {
                    if (ni.OperationalStatus == OperationalStatus.Up)
                        candidates.Add(ni);
                }
            }

            if (candidates.Count == 1)
            {
                return candidates[0];
            }

            // Accoring to our tech, the main NetworkInterface should have a Gateway 
            // and it should be the ony one with a gateway.
            if (candidates.Count > 1)
            {
                for (int n = candidates.Count - 1; n >= 0; n--)
                {
                    if (candidates[n].GetIPProperties().GatewayAddresses.Count == 0)
                    {
                        candidates.RemoveAt(n);
                    }
                }

                if (candidates.Count == 1)
                {
                    return candidates[0];
                }
            }

            // Fallback to try by getting my ipAdress from the dns
            IPAddress myMainIpAdress = null;
            IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress ip in host.AddressList)
            {
                if (ip.AddressFamily == AddressFamily.InterNetwork) // Get the first IpV4
                {
                    myMainIpAdress = ip;
                    break;
                }
            }

            if (myMainIpAdress != null)
            {
                NetworkInterface[] NetworkInterfaces =
                    NetworkInterface.GetAllNetworkInterfaces();

                foreach (NetworkInterface ni in NetworkInterfaces)
                {
                    if (ni.OperationalStatus == OperationalStatus.Up)
                    {
                        IPInterfaceProperties props = ni.GetIPProperties();
                        foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
                        {
                            if (ai.Address.Equals(myMainIpAdress))
                            {
                                return ni;
                            }
                        }
                    }
                }
            }

            return null;
        }

        // ******************************************************************
        /// <summary>
        /// AddressFamily.InterNetwork = IPv4
        /// Thanks to Dr. Wilys Apprentice at
        /// http://stackoverflow.com/questions/1069103/how-to-get-the-ip-address-of-the-server-on-which-my-c-sharp-application-is-runni
        /// using System.Net.NetworkInformation;
        /// </summary>
        /// <param name="mac"></param>
        /// <param name="addressFamily">AddressFamily.InterNetwork = IPv4,  AddressFamily.InterNetworkV6 = IPv6</param>
        /// <returns></returns>
        public static IPAddress GetIpFromMac(PhysicalAddress mac, AddressFamily addressFamily = AddressFamily.InterNetwork)
        {
            NetworkInterface[] NetworkInterfaces =
                NetworkInterface.GetAllNetworkInterfaces();

            foreach (NetworkInterface ni in NetworkInterfaces)
            {
                if (ni.GetPhysicalAddress().Equals(mac))
                {
                    if (ni.OperationalStatus == OperationalStatus.Up)
                    {
                        IPInterfaceProperties props = ni.GetIPProperties();
                        foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
                        {
                            if (ai.DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred)
                            {
                                if (ai.Address.AddressFamily == addressFamily)
                                {
                                    return ai.Address;
                                }
                            }
                        }
                    }
                }
            }

            return null;
        }

        // ******************************************************************
        /// <summary>
        /// Return the best guess of main ipAdress. To get it in the form aaa.bbb.ccc.ddd just call 
        /// '?.ToString() ?? ""' on the result.
        /// </summary>
        /// <returns></returns>
        public static IPAddress GetMyInternetIpAddress()
        {
            NetworkInterface ni = GetMainNetworkInterface();
            IPAddress ipAddress = GetIpFromMac(ni.GetPhysicalAddress());
            if (ipAddress == null) // could it be possible ?
            {
                ipAddress = GetIpFromMac(ni.GetPhysicalAddress(), AddressFamily.InterNetworkV6);
            }

            return ipAddress;
        }

        // ******************************************************************
        public static bool IsBroadcastAddress(IPAddress ipAddress)
        {
            if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
            {
                return ipAddress.GetAddressBytes()[3] == 255;
            }

            if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
            {
                return false; // NO broadcast in IPv6
            }

            return false;
        }

        // ******************************************************************
        public static bool IsMulticastAddress(IPAddress ipAddress)
        {
            if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
            {
                // Source: https://technet.microsoft.com/en-us/library/cc772041(v=ws.10).aspx
                return ipAddress.GetAddressBytes()[0] >= 224 && ipAddress.GetAddressBytes()[0] <= 239;
            }

            if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
            {
                return ipAddress.IsIPv6Multicast;
            }

            return false;
        }

        // ******************************************************************

    }
}
Eric Ouellet
źródło
1

Jeszcze innym sposobem uzyskania publicznego adresu IP jest użycie resolve1.opendns.comserwera OpenDNS myip.opendns.comjako żądania.

W wierszu polecenia jest to:

  nslookup myip.opendns.com resolver1.opendns.com

Lub w języku C # za pomocą programu użytkowego DNSClient:

  var lookup = new LookupClient(new IPAddress(new byte[] { 208, 67, 222, 222 }));
  var result = lookup.Query("myip.opendns.com", QueryType.ANY);

Jest to nieco czystsze niż uderzanie punktów końcowych HTTP i analizowanie odpowiedzi.

Ian Mercer
źródło
0

Ma to na celu uzyskanie wszystkich lokalnych adresów IP w formacie csv w VB.NET

Imports System.Net
Imports System.Net.Sockets

Function GetIPAddress() As String
    Dim ipList As List(Of String) = New List(Of String)
    Dim host As IPHostEntry
    Dim localIP As String = "?"
    host = Dns.GetHostEntry(Dns.GetHostName())
    For Each ip As IPAddress In host.AddressList
        If ip.AddressFamily = AddressFamily.InterNetwork Then
            localIP = ip.ToString()
            ipList.Add(localIP)
        End If
    Next
    Dim ret As String = String.Join(",", ipList.ToArray)
    Return ret
End Function
Saurabh Kumar
źródło
0

Aby uzyskać zdalny adres IP w najszybszy możliwy sposób. Musisz użyć downloadera lub utworzyć serwer na swoim komputerze.

Wadą używania tego prostego kodu: (który jest zalecany) jest to, że uzyskanie zdalnego adresu IP zajmie 3-5 sekund, ponieważ po zainicjowaniu WebClient zawsze sprawdza ustawienia proxy.

 public static string GetIP()
 {
            string externalIP = "";
            externalIP = new WebClient().DownloadString("http://checkip.dyndns.org/");
            externalIP = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"))
                                           .Matches(externalIP)[0].ToString();
            return externalIP;
 }

Oto jak to naprawiłem .. (pierwszy raz nadal zajmuje 3-5 sekund), ale potem zawsze uzyska Twój zdalny adres IP w ciągu 0-2 sekund, w zależności od połączenia.

public static WebClient webclient = new WebClient();
public static string GetIP()
{
    string externalIP = "";
    externalIP = webclient.DownloadString("http://checkip.dyndns.org/");
    externalIP = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"))
                                   .Matches(externalIP)[0].ToString();
    return externalIP;
}
SSpoke
źródło
Dlaczego głosowanie negatywne? nie możesz znaleźć odpowiedzi szybciej lub lepiej niż to ... za każdym razem inicjowanie WebClient ma duże opóźnienie ogólne.
SSpoke