Yerel IP adresi al


301

İnternette nasıl IP adresi alacağınızı gösteren birkaç yer var. Ve birçoğu bu örneğe benziyor:

String strHostName = string.Empty;
// 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);
// 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());
}
Console.ReadLine();

Bu örnekle birkaç IP adresi alıyorum, ancak yalnızca yönlendiricinin programı çalıştıran bilgisayara atadığı adresi almakla ilgileniyorum: bilgisayarımdaki paylaşılan bir klasöre erişmek istiyorsa birisine vereceğim IP örneği.

Bir ağa bağlı değilsem ve yönlendiricisiz bir modem aracılığıyla doğrudan internete bağlıysam, bir hata almak istiyorum. Bilgisayarımın C # ile bir ağa bağlı olup olmadığını ve LAN IP adresini almak için nasıl olduğunu nasıl görebilirim.


If I am not connected to a network and I am connected to the internet Bu ifade çelişkili görünüyor. Bilgisayarınızın özel bir LAN'a veya İnternet'e bağlı olup olmadığını anlamaya mı çalışıyorsunuz?
Andy

4
Bir uyarı olarak: Bir bilgisayarda LAN ve WiFi gibi birden fazla IP arayüzü olabilir. Bir servisi belirli bir donanıma (LAN diyelim) bağlarsanız, LAN'ın IP'sine ihtiyacınız vardır. Aşağıdaki örneklerin çoğu bulunan "ilk" veya "son" IP adresini döndürür. 2'den fazla IP adresiniz varsa, işletim sisteminizin IP adreslerini döndürdüğü rasgele sıraya bağlı olarak programınız% 50 oranında çalışabilir.
Mark Lakata

@ MarkLakata Aynı konuyu düşündüm. Aşağıdaki cevabımdaki işlev bunun üstesinden gelecek. IP adresinin hangi ağ arayüzü türünden olmasını istediğinizi belirleyebilirsiniz.
compman2408

3
Sadece FTR, burada Unity3D için google, onların API'sında Network.player.ipAddress
Fattie

@MarkLakata açık konuşmak gerekirse, "ilk" ya da "son" IP olan tarayıcı kullanılabilir herhangi IP kullanmak olabileceğinden "doğru" IP. Muhtemelen iyi bir düzeltme , makineyle ilişkili her IP'yi döndürmek olmalıdır .
UncaAlby

Yanıtlar:


457

Yerel IP Adresini almak için:

public static string GetLocalIPAddress()
{
    var host = Dns.GetHostEntry(Dns.GetHostName());
    foreach (var ip in host.AddressList)
    {
        if (ip.AddressFamily == AddressFamily.InterNetwork)
        {
            return ip.ToString();
        }
    }
    throw new Exception("No network adapters with an IPv4 address in the system!");
}

Bağlı olup olmadığınızı kontrol etmek için:

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();


29
sanal kutu, genymotion vb. gibi şeyler kullanırsanız çalışmaz
PauLEffect

5
PaulEffect ile aynı fikirde. Sadece bu yöntem birden fazla ağ kartı için kötü değildir, aynı zamanda IP v6 ve IP v4 adresleri arasında ayrım yapmaz.
Max

16
@John AddressFamily.InterNetwork, IP v4 ve AddressFamily.InterNetworkV6, IP v6
Leonardo Xavier

Ben Geraldo H Cevap kullanıyorum, ancak herkes bunu kullanıyorsa, 1 ile biten tüm ips kaldırmak isteyebilirsiniz, bu yüzden geri döngü ve sanal kutu / vmware varsayılan ips kaldırır
Leonardo Xavier

6
Görünüşe göre VMWare veya başka bir sanallaştırma yazılımı kullanıyorsunuz. OP bunu istemedi, bu yüzden aşağı oylama nedeniyle biraz sert olduğunu düşünüyorum. VMWare veya birden çok NIC'niz varsa, diğer yanıtların bazıları zaten bununla ilgili ipuçları sağlar.
Mrchief

218

Yerel makinede çoklu ip adresleri olduğunda daha doğru bir yol var. Connectbir UDP soketi ve yerel uç noktasını okuyun:

string localIP;
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
{
    socket.Connect("8.8.8.8", 65530);
    IPEndPoint endPoint = socket.LocalEndPoint as IPEndPoint;
    localIP = endPoint.Address.ToString();
}

Connectbir UDP soketinde aşağıdaki etkiye sahiptir: Send/ için hedefi ayarlar, Recvdiğer adreslerden tüm paketleri atar ve - kullandığımız bu - soketi "bağlı" duruma aktarır, uygun alanlarını ayarlar. Bu, sistemin yönlendirme tablosuna göre hedefe giden yolun varlığını kontrol etmeyi ve yerel bitiş noktasını buna göre ayarlamayı içerir. Son bölüm resmi olarak belgelenmemiş gibi görünüyor, ancak sürümler ve dağıtımlar arasında hem Windows hem de Linux'ta güvenilir bir şekilde çalışan Berkeley soketleri API'sının (UDP "bağlı" durumunun bir yan etkisi) ayrılmaz bir özelliğine benziyor .

Bu nedenle, bu yöntem belirtilen uzak ana bilgisayara bağlanmak için kullanılacak yerel adresi verecektir. Gerçek bir bağlantı kurulmamıştır, bu nedenle belirtilen uzak ip erişilemez.


4
Bu, ihtiyaçlarım için çalışan en iyi çözüm. Benim durumumda birçok ağ kartı ve birkaç kablosuz bağlantı var. Hangi bağlantının etkinleştirildiğine bağlı olarak tercih edilen IP adresini almam gerekiyordu.
David

10
Ağ bağlantısı olmadan - yine de IP adresiniz yok. Bu nedenle, kod hala geçerli olarak kalır, ancak böyle bir durumu işlemek için bir try..catch eklemek ve bir SocketException atıldığında "127.0.0.1" gibi bir şey döndürmek akıllıca olacaktır.
Russ

2
@PatrickSteele, evet, belirli bir hedef için tercih edilen giden ip adresini döndürür. LAN ip adresinizi almak istiyorsanız, LAN'ınızdan bir ip olmak için hedefi belirtmeye çalışın
Next Door'dan Mr.Wang,

2
Bu yöntem dotnet çekirdeği olan bir mac üzerinde çalışıyor, ancak kabul edilen cevap şu anda çalışmıyor.
Pelet

9
Bu çözüm, kabul edilen cevaptan (Mrchief tarafından) yaklaşık 4 kat daha hızlı çalışır. Bu gerçek cevap olmalı
Kamarey

115

Linche'den yararlanmak için Mrcheif'in kodunu yeniden düzenleme (ör. Net 3.0+). .

private IPAddress LocalIPAddress()
{
    if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
    {
        return null;
    }

    IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());

    return host
        .AddressList
        .FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
}

:)


"Inter Network" olarak birkaç IP Adresim var, bu çözüm aslında işe yarıyor ve doğru olanı geri veriyor. Mrchief'ten diğeri bana sonuncusunu veriyor. Yani aslında bu doğru olanı olmalı;)
Keenora Fluffball

26
@KeenoraFluffball - bu size birincisini verirken, bu size sonuncuyu verir (ya da tam tersi, listenin nasıl oluşturulduğuna bağlıdır). Her iki durumda da, ikisi de doğru değildir; size verilen 1'den fazla IP adresi varsa, hangi ağı kullandığınızı bilmeniz gerekir. İlk veya sonuncuyu alarak tahmin etmek doğru çözüm değildir.
gbjbaanb


ağ mevcut değilse null dönüşü, bağımsız PC'leri de kullanmanız gerektiğinde yararlı değildir. Ben "return IPAddress.Loopback;" 127.0.0.1 özel IP numarasına karşılık gelir.
Christian

109

Bunun ölü bir atı tekmelemek olabileceğini biliyorum, ama belki bu birine yardım edebilir. Yerel IP adresimi bulmak için her yere baktım, ancak bulduğum her yerde kullanmak diyor:

Dns.GetHostEntry(Dns.GetHostName());

Bunu hiç sevmiyorum çünkü sadece bilgisayarınıza atanan tüm adresleri alıyor. Birden fazla ağ arabiriminiz varsa (hemen hemen tüm bilgisayarlar günümüzde bunu yapmaktadır) hangi ağ arabirimiyle hangi adresin gittiğini bilmiyorsunuz. Bir sürü araştırma yaptıktan sonra, NetworkInterface sınıfını kullanmak için bir işlev oluşturdum ve bilgiyi bundan çıkardım. Bu şekilde ne tür bir arayüz olduğunu (Ethernet, kablosuz, geridöngü, tünel vb.), Aktif olup olmadığını ve SOOO'yu çok daha fazla söyleyebilirim.

public string GetLocalIPv4(NetworkInterfaceType _type)
{
    string output = "";
    foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
    {
        if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
        {
            foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
            {
                if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
                {
                    output = ip.Address.ToString();
                }
            }
        }
    }
    return output;
}

Şimdi Ethernet ağ arayüzü çağrınızın IPv4 adresini almak için:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

Veya Kablosuz arayüzünüz:

GetLocalIPv4(NetworkInterfaceType.Wireless80211);

Kablosuz arabirim için IPv4 adresi almaya çalışırsanız, ancak bilgisayarınızda kablosuz kart takılı değilse, boş bir dize döndürür. Ethernet arayüzü ile aynı şey.

Umarım bu birine yardımcı olur! :-)

DÜZENLE:

Bu işlev, IP adresini kullanmaktan çok daha iyi bir şekilde çıkarmaya devam etmesine rağmen Dns.GetHostEntry(Dns.GetHostName()), tek bir arabirimde aynı türden birden fazla arabirimi veya birden çok IP adresini desteklemede çok iyi sonuç vermediğine dikkat çekti (teşekkürler @NasBanov). . Yalnızca birden fazla adres atanmışsa tek bir IP adresi döndürür. Atanan bu adreslerin TÜMÜ'nü döndürmek için, orijinal işlevi, tek bir dize yerine her zaman bir dizi döndürecek şekilde değiştirebilirsiniz. Örneğin:

public static string[] GetAllLocalIPv4(NetworkInterfaceType _type)
{
    List<string> ipAddrList = new List<string>();
    foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
    {
        if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
        {
            foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
            {
                if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
                {
                    ipAddrList.Add(ip.Address.ToString());
                }
            }
        }
    }
    return ipAddrList.ToArray();
}

Şimdi bu işlev belirli bir arabirim türü için TÜM atanmış adresleri döndürecektir. Şimdi sadece tek bir dize almak .FirstOrDefault()için, dizideki ilk öğeyi döndürmek için uzantıyı kullanabilirsiniz veya boşsa boş bir dize döndürebilirsiniz.

GetLocalIPv4(NetworkInterfaceType.Ethernet).FirstOrDefault();

5
Bu daha iyi bir çözümdür çünkü birçok yerde DNS kullanılabilirliği yoktur ve arayüzlerde birden fazla ip adresi olabilir. Ben de benzer bir yöntem kullanıyorum.
Mert Gülsoy

Bununla ilgili sorun, her arabirim için yalnızca 1 IP adresi döndürmenizdir ... son IP, her foreach.
Nas Banov

@ compman2408 - doğru değil, tek bir arabirimin birden fazla IP'si olabilir, bkz . tüm kombinasyonlar için en.wikipedia.org/wiki/Multihoming#Variants . Açık bir örnek hem IPv4 hem de IPv6'yı çalıştırırken, ancak geçmişte birden fazla IPv4 ağına katılan tek bir ethernet adaptörüne sahiptim. Olağandışı belki - henüz mükemmel yasal. Windows için Örn bkz windowsnetworking.com/articles-tutorials/windows-2003/...
Nas Banov

@NasBanov Bu işlev yalnızca IPv4 adreslerini almak için ayarlanmıştır, bu yüzden IPv6 ve şu andaki yararsızlığı hakkında konuşmayacağım bile. Birden fazla arabirimde birden çok ağa bağlanma olarak çoklu ana bilgisayar bilgisinin farkındayım, ancak aynı arabirimde birden çok ağa bağlandığını hiç duymadım. Gerçekte mümkün olduğu doğru görünse de, NIC'lerini bu şekilde kullananların <% 1'i bir dizi döndürmek için işlevi değiştirmek zorunda kalacak.
compman2408

1
Bunun için teşekkür ederim. FYI, en azından OS 3.5 üzerinde .NET 3.5 mono üzerinde item.OperationalStatusher zaman geri döner Unknown.
gman

36

İşte benim için çalışan değiştirilmiş bir sürüm (compman2408'inkinden):

    internal static string GetLocalIPv4(NetworkInterfaceType _type)
    {  // Checks your IP adress from the local network connected to a gateway. This to avoid issues with double network cards
        string output = "";  // default output
        foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces()) // Iterate over each network interface
        {  // Find the network interface which has been provided in the arguments, break the loop if found
            if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
            {   // Fetch the properties of this adapter
                IPInterfaceProperties adapterProperties = item.GetIPProperties();
                // Check if the gateway adress exist, if not its most likley a virtual network or smth
                if (adapterProperties.GatewayAddresses.FirstOrDefault() != null)
                {   // Iterate over each available unicast adresses
                    foreach (UnicastIPAddressInformation ip in adapterProperties.UnicastAddresses)
                    {   // If the IP is a local IPv4 adress
                        if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                        {   // we got a match!
                            output = ip.Address.ToString();
                            break;  // break the loop!!
                        }
                    }
                }
            }
            // Check if we got a result if so break this method
            if (output != "") { break; }
        }
        // Return results
        return output;
    }

Bu yöntemi örneğin şöyle çağırabilirsiniz:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

Değişiklik: IP atanmış bir ağ geçidi IP olan bir bağdaştırıcıdan alıyorum. İkinci değişiklik: Bu yöntemi daha verimli hale getirmek için docstrings ve break ifadelerini ekledim.


2
Akıllı çözüm. Şimdi bunu kullanıyorum.
RQDQ

4
Türetildiği kod gibi aynı sorunu var: sadece IP'lerden birini, birçok rastgele bir IP döndürür - ihtiyacınız olan biri olmak zorunda değildir. Ademiller.com/blogs/tech/2008/06/it-works-on-my-machine-award
Nas Banov

1
@NasBanov, Elbette kazandım, yazımda söylediğim gibi: "benim için işe yaradı". :-)
Gerardo H

Bu yol, bunun için teşekkürler. Takılı emülatörler için geri döngü anahtarları varsa, bu başarılı olurken diğer tüm değişkenler başarısız olur!
DiamondDrake

1
Neden sadece bulduğunuz son ip adresini döndürüyorsunuz, ilkini değil? breakEn içteki bir basit ifya da bir returnhile yapar.
Martin Mulder

20

Bu, mevcut IP'yi almak için bulduğum en iyi kod, VMWare ana bilgisayarını veya diğer geçersiz IP adresini almaktan kaçındı.

public string GetLocalIpAddress()
{
    UnicastIPAddressInformation mostSuitableIp = null;

    var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();

    foreach (var network in networkInterfaces)
    {
        if (network.OperationalStatus != OperationalStatus.Up)
            continue;

        var properties = network.GetIPProperties();

        if (properties.GatewayAddresses.Count == 0)
            continue;

        foreach (var address in properties.UnicastAddresses)
        {
            if (address.Address.AddressFamily != AddressFamily.InterNetwork)
                continue;

            if (IPAddress.IsLoopback(address.Address))
                continue;

            if (!address.IsDnsEligible)
            {
                if (mostSuitableIp == null)
                    mostSuitableIp = address;
                continue;
            }

            // The best IP is the IP got from DHCP server
            if (address.PrefixOrigin != PrefixOrigin.Dhcp)
            {
                if (mostSuitableIp == null || !mostSuitableIp.IsDnsEligible)
                    mostSuitableIp = address;
                continue;
            }

            return address.Address.ToString();
        }
    }

    return mostSuitableIp != null 
        ? mostSuitableIp.Address.ToString()
        : "";
}

Muhtemelen bu kodun neden cevabın çözümü olduğunu açıklamalısınız. İnternete bağlıysanız ve bu bir hatayla sonuçlanıyorsa soruya gerçekten bir cevap alabilir misiniz?
Philipp M

Diğer yollar IsDnsEligible ve PrefixOrigin doğrulamasını kullanmaz.
rodcesar.santos

@PhilippM Adres bir DNS Uygun Değilse, ayrılmış bir dahili IP'dir. İnternet sağlayıcısı değil. PrefixOrigin bir DHCP sunucusu tarafından sağlandıysa, bu en iyi adres seçimidir. Bu benim için çalışan benzersiz bir işlev!
rodcesar.santos

1
@ user1551843 - harikaydı, teşekkürler. Eski amortismanlı GetHostByName yöntemini kullanıyordum ama bir VMWare bağdaştırıcısının IP'sini döndürüyordu :)
Jason Newland

Bu benim için vpn + kablosuz üzerinde çalışan tek çözümdü. Teşekkür ederim.
jay-danger

12

LinQ kullanmanın daha kolay olduğunu düşünüyorum:

Dns.GetHostEntry(Dns.GetHostName())
   .AddressList
   .First(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
   .ToString()

14
Bu LINQ değil, uzatma yöntemleri ve lambdalar. Bir fark var.
Mark

10
@Mark - "using System.Linq;" "İlk" uzantı yöntemini
kullanamazsınız

5
Uzantı yöntemi System.Linq ad alanında bulunan Enumerable sınıfında olmasıdır. Hala LINQ değil.
Mark

20
Mark, bu kısa formda bile, ifade aslında yöntem (lambda) sözdizimi ile sunulan LINQ-nesneler kullanıyor. Sorgu sözdizimi, basitçe LINQ-to-nesneler olan IEnumerable uzatma yöntemi çağrıları zincirine derlenen sözdizimsel şekerdir. Kaynaklar: konuyla ilgili bir LINQ-SQL sağlayıcısı ve bir dizi makale yazdı.
constantine g


9

Bir kahkaha için, yeni C # 6 null koşullu işleci kullanarak tek bir LINQ deyimi almaya çalışacağımı düşündüm. Oldukça çılgın ve muhtemelen korkunç verimsiz görünüyor, ama işe yarıyor.

private string GetLocalIPv4(NetworkInterfaceType type = NetworkInterfaceType.Ethernet)
{
    // Bastardized from: http://stackoverflow.com/a/28621250/2685650.

    return NetworkInterface
        .GetAllNetworkInterfaces()
        .FirstOrDefault(ni =>
            ni.NetworkInterfaceType == type
            && ni.OperationalStatus == OperationalStatus.Up
            && ni.GetIPProperties().GatewayAddresses.FirstOrDefault() != null
            && ni.GetIPProperties().UnicastAddresses.FirstOrDefault(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork) != null
        )
        ?.GetIPProperties()
        .UnicastAddresses
        .FirstOrDefault(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork)
        ?.Address
        ?.ToString()
        ?? string.Empty;
}

Mantık izniyle Gerardo H(ve referans olarak compman2408).


Kesinlikle eğlenceli (+1), ama aslında hiç verimsiz olması gerekmez. Bana LISP veya Forth'da programlama hatırlatıyor :-)
Roland

6

Linq ifadesini kullanarak IP almanın diğer yolu:

public static List<string> GetAllLocalIPv4(NetworkInterfaceType type)
{
    return NetworkInterface.GetAllNetworkInterfaces()
                   .Where(x => x.NetworkInterfaceType == type && x.OperationalStatus == OperationalStatus.Up)
                   .SelectMany(x => x.GetIPProperties().UnicastAddresses)
                   .Where(x => x.Address.AddressFamily == AddressFamily.InterNetwork)
                   .Select(x => x.Address.ToString())
                   .ToList();
}

5

@mrcheif Bu yanıtı bugün buldum ve yanlış bir IP (kod çalışmıyor nedeniyle değil) döndü, ancak çok yararlı oldu ama Himachi gibi şeyler olduğunda yanlış internetwork IP verdi.

public static string localIPAddress()
{
    IPHostEntry host;
    string localIP = "";
    host = Dns.GetHostEntry(Dns.GetHostName());

    foreach (IPAddress ip in host.AddressList)
    {
        localIP = ip.ToString();

        string[] temp = localIP.Split('.');

        if (ip.AddressFamily == AddressFamily.InterNetwork && temp[0] == "192")
        {
            break;
        }
        else
        {
            localIP = null;
        }
    }

    return localIP;
}

2
Şunu mu demek istediniz: Logmein Hamachi? Bir VPN çözümüdür ve ağ yığını ile uğraşır. Ayrıca, bir VPN olarak, bağlandığında VPN tarafından atanan IP'yi döndürmesi makul görünmektedir (sadece tahminim).
Ocak'ta Mrchief

2
Tamamen Güvenilmez. Sadece 192.0.0.0/8özel bir IP adresi için doğru bir test olmakla kalmaz (hepsi bundan farklı olan 3 aralık vardır), aynı zamanda kurumsal bir ağ aralığı olabilir, bu yüzden çok "yerel" olmayabilir.
ivan_pozdeev

5

Bir veya daha fazla LAN kartı ve Sanal makine ile test edilmiştir

public static string DisplayIPAddresses()
    {
        string returnAddress = String.Empty;

        // 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)
        {
            // Read the IP configuration for each network
            IPInterfaceProperties properties = network.GetIPProperties();

            if (network.NetworkInterfaceType == NetworkInterfaceType.Ethernet &&
                   network.OperationalStatus == OperationalStatus.Up &&
                   !network.Description.ToLower().Contains("virtual") &&
                   !network.Description.ToLower().Contains("pseudo"))
            {
                // 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;

                    returnAddress = address.Address.ToString();
                    Console.WriteLine(address.Address.ToString() + " (" + network.Name + " - " + network.Description + ")");
                }
            }
        }

       return returnAddress;
    }

Bunun yalnızca Ethernet için çalıştığını unutmayın. Wi-fi'yi desteklemek için NetworkInterfaceType kısıtlamasını kaldırın.
scor4er

3

LINQ kullanarak güncellenmiş bir versiyonum:

/// <summary>
/// Gets the local Ipv4.
/// </summary>
/// <returns>The local Ipv4.</returns>
/// <param name="networkInterfaceType">Network interface type.</param>
IPAddress GetLocalIPv4(NetworkInterfaceType networkInterfaceType)
{
    var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces().Where(i => i.NetworkInterfaceType == networkInterfaceType && i.OperationalStatus == OperationalStatus.Up);

    foreach (var networkInterface in networkInterfaces)
    {
        var adapterProperties = networkInterface.GetIPProperties();

        if (adapterProperties.GatewayAddresses.FirstOrDefault() == null)
                continue;
        foreach (var ip in networkInterface.GetIPProperties().UnicastAddresses)
        {
            if (ip.Address.AddressFamily != AddressFamily.InterNetwork)
                    continue;

            return ip.Address;
        }
    }

    return null;
}

2

Ön koşullar: System.Data.Linq referansını eklemeniz ve referans vermeniz gerekir

using System.Linq;
string ipAddress ="";
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
ipAddress = Convert.ToString(ipHostInfo.AddressList.FirstOrDefault(address => address.AddressFamily == AddressFamily.InterNetwork));

2

Ayrıca doğru IP'yi elde etmekle uğraşıyordum.

Burada çeşitli çözümler denedim ama hiçbiri bana istenen etkiyi sağladı. Sağlanan koşullu testlerin neredeyse tamamı adres kullanılmasına neden olmamıştır.

Bu benim için işe yaradı, umarım yardımcı olur ...

var firstAddress = (from address in NetworkInterface.GetAllNetworkInterfaces().Select(x => x.GetIPProperties()).SelectMany(x => x.UnicastAddresses).Select(x => x.Address)
                    where !IPAddress.IsLoopback(address) && address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork
                    select address).FirstOrDefault();

Console.WriteLine(firstAddress);

1
string str="";

System.Net.Dns.GetHostName();

IPHostEntry ipEntry = System.Net.Dns.GetHostEntry(str);

IPAddress[] addr = ipEntry.AddressList;

string IP="Your Ip Address Is :->"+ addr[addr.Length - 1].ToString();

str her zaman boştur
aj.toulan

1

Genel durumda, birden fazla NAT çevirinizin ve her biri farklı NAT çeviri düzeylerinde çalışan birden çok dns sunucunuzun olabileceğini unutmayın.

Taşıyıcı dereceli NAT'niz varsa ve aynı operatörün diğer müşterileriyle iletişim kurmak istiyorsanız ne olur? Genel durumda hiçbir zaman kesin olarak bilemezsiniz çünkü her NAT çevirisinde farklı ana bilgisayar adlarıyla görünebilirsiniz.


1

Eski gitti, bu benim için çalışıyor

public static IPAddress GetIPAddress()
{ 
 IPAddress ip = Dns.GetHostAddresses(Dns.GetHostName()).Where(address => 
 address.AddressFamily == AddressFamily.InterNetwork).First();
 return ip;
}

1

Mrchief'in cevabını Linq ile güncellediğimizde:

public static IPAddress GetLocalIPAddress()
{
   var host = Dns.GetHostEntry(Dns.GetHostName());
   var ipAddress= host.AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
   return ipAddress;
}

1

Bu, IPV4 ve IPV6 olmak üzere iki ayrı listede ağ geçidi adresi ve tek noktaya yayın adresi olan tüm arabirimlerdeki adresleri döndürür.

public static (List<IPAddress> V4, List<IPAddress> V6) GetLocal()
{
    List<IPAddress> foundV4 = new List<IPAddress>();
    List<IPAddress> foundV6 = new List<IPAddress>();

    NetworkInterface.GetAllNetworkInterfaces().ToList().ForEach(ni =>
    {
        if (ni.GetIPProperties().GatewayAddresses.FirstOrDefault() != null)
        {
            ni.GetIPProperties().UnicastAddresses.ToList().ForEach(ua =>
            {
                if (ua.Address.AddressFamily == AddressFamily.InterNetwork) foundV4.Add(ua.Address);
                if (ua.Address.AddressFamily == AddressFamily.InterNetworkV6) foundV6.Add(ua.Address);
            });
        }
    });

    return (foundV4.Distinct().ToList(), foundV6.Distinct().ToList());
}

Temiz çözüm :)
Johan Franzén

1

Zaten birçok cevap var, ama hala benimkine katkıda bulunuyorum:

public static IPAddress LocalIpAddress() {
    Func<IPAddress, bool> localIpPredicate = ip =>
        ip.AddressFamily == AddressFamily.InterNetwork &&
        ip.ToString().StartsWith("192.168"); //check only for 16-bit block
    return Dns.GetHostEntry(Dns.GetHostName()).AddressList.LastOrDefault(localIpPredicate);
}

Bir astar:

public static IPAddress LocalIpAddress() => Dns.GetHostEntry(Dns.GetHostName()).AddressList.LastOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork && ip.ToString().StartsWith("192.168"));

not: MobileHotspot, VPN veya diğer süslü sanal adaptörler gibi bazı arayüzler eklendikten sonra hala çalıştığı için sondan ara.


1
Yerel IP adresim 10.0.2.3 ise bulunamadı? Bu kodda gerçekten garip.
frankhommers

@frankhommers sadece 16-bit blok için kontrol
nyconing

16 bitlik bloklar
192.168'den

0

Ayrıca İstemci Ip almak için sadece basit bir kod:

        public static string getclientIP()
        {
            var HostIP = HttpContext.Current != null ? HttpContext.Current.Request.UserHostAddress : "";
            return HostIP;
        }

Umarım size yardımcı olur.


0
Dns.GetHostEntry(Dns.GetHostName()).AddressList[1].MapToIPv4() //returns 192.168.14.1

resim açıklamasını buraya girin


5
Cevabınız, OP ve gelecekteki okuyucular için nasıl çalıştığına dair bir açıklama içermelidir.
Ronak Dhoot

Gelecekteki okuyucular için cevabınızın bir açıklamasını eklemek daha iyidir.
Nicolas Gervais

0

Compman2408'in kodu, her birini tekrarlayabilmek için değiştirildi NetworkInterfaceType.

public static string GetLocalIPv4 (NetworkInterfaceType _type) {
    string output = null;
    foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces ()) {
        if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up) {
            foreach (UnicastIPAddressInformation ip in item.GetIPProperties ().UnicastAddresses) {
                if (ip.Address.AddressFamily == AddressFamily.InterNetwork) {
                    output = ip.Address.ToString ();
                }
            }
        }
    }
    return output;
}

Ve şöyle diyebilirsiniz:

static void Main (string[] args) {
    // Get all possible enum values:
    var nitVals = Enum.GetValues (typeof (NetworkInterfaceType)).Cast<NetworkInterfaceType> ();

    foreach (var nitVal in nitVals) {
        Console.WriteLine ($"{nitVal} => {GetLocalIPv4 (nitVal) ?? "NULL"}");
    }
}

0
Imports System.Net
Imports System.Net.Sockets
Function LocalIP()
    Dim strHostName = Dns.GetHostName
    Dim Host = Dns.GetHostEntry(strHostName)
    For Each ip In Host.AddressList
        If ip.AddressFamily = AddressFamily.InterNetwork Then
            txtIP.Text = ip.ToString
        End If
    Next

    Return True
End Function

Aynı işlemin altında

İşlev LocalIP ()

Dim Host As String = Dns.GetHostEntry (Dns.GetHostName) .AddressList (1) .MapToIPv4.ToString

txtIP.Text = Ana Bilgisayar

Doğru Dönüş

Bitiş Fonksiyonu


Aşağıdaki örnek aynı eylemdir Function LocalIP () Dim Host As String = Dns.GetHostEntry (Dns.GetHostName) .AddressList (1) .MapToIPv4.ToString txtIP.Text = Host Dönüş Gerçek Sonu İşlevi
YongJae Kim

-2
Dns.GetHostEntry(Dns.GetHostName()).AddressList[1]

bir satır kod: D


7
Bazı durumlarda bir OutOfRangeException kurabilir.
Loudenvier

5
Ayrıca, hangisini istediğinizi nereden biliyorsunuz? Sizin için doğru olan başka biri için yanlış olabilir.
Mark

-3

Sanal makineleriniz veya fazladan ağ kartlarınız varsa, adres listesinde başka değerler olabilir. Benim önerim adres listesinin girişlerini kontrol etmek ve uygun olanı yazdırmak. Benim durumumda giriş 3 makinemin ipv4 adresi oldu

IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddr = ipHost.AddressList[3];
string ip = ipAddr.ToString();

Eklemeyi unutma using System.Net;


1
Düzeltme; TÜMÜ makinenizin IP adresidir. Ancak hangisini istediğiniz başka bir hikaye. Siparişin değişebileceğini ve kullandığınız yönteme bağlı olarak her zaman tahmin edeceğinizi unutmayın.
Mark

Söylediğim gibi, adres listesinin girişlerini kontrol etmelisiniz ve evet tahmin ediyor, ancak tüm girişleri gördükten sonra tahmin etmek çok zor değil
Bibaswann Bandyopadhyay

Hangisinin uygun olduğunu nasıl bilebilirsiniz? Compman2048'in çözümünü kullanarak, en azından hangisinin hangi arayüze bağlı olduğunu bilirsiniz.
Mark

Bu çözüm bilgisayarımda çalışmadı, çünkü 2 wlan arabirimim, 2 sanal makinem ve 1 emülatörüm var, bu yüzden çok fazla IP'im var. Ancak yönlendirici tarafından sağlanan dahili adresi arıyorsanız, 192 veya 172 veya 10 ile başlayacaktır, bu şekilde anladım
Bibaswann Bandyopadhyay

Yönlendiriciniz genel IP'leri dağıtmadığı sürece, bu nadir ancak mümkündür.
Mark
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.