Dapatkan alamat IP lokal


301

Di internet ada beberapa tempat yang menunjukkan kepada Anda cara mendapatkan alamat IP. Dan banyak dari mereka terlihat seperti contoh ini:

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

Dengan contoh ini saya mendapatkan beberapa alamat IP, tetapi saya hanya tertarik untuk mendapatkan alamat yang diberikan oleh router ke komputer yang menjalankan program: IP yang akan saya berikan kepada seseorang jika ia ingin mengakses folder bersama di komputer saya untuk contoh.

Jika saya tidak terhubung ke jaringan dan saya terhubung ke internet secara langsung melalui modem tanpa router maka saya ingin mendapatkan kesalahan. Bagaimana saya bisa melihat apakah komputer saya terhubung ke jaringan dengan C # dan jika kemudian mendapatkan alamat IP LAN.


If I am not connected to a network and I am connected to the internet Pernyataan ini sepertinya kontradiktif. Apakah Anda mencoba mencari tahu apakah komputer Anda terhubung ke LAN pribadi atau Internet?
Andy

4
Sama seperti peringatan: Komputer dapat memiliki lebih dari satu antarmuka IP, misalnya LAN dan WiFi. Jika Anda mengikat layanan ke perangkat keras tertentu (katakanlah LAN), Anda memerlukan IP LAN. Sebagian besar contoh berikut akan mengembalikan alamat IP "pertama" atau "terakhir" yang ditemukan. Jika Anda memiliki lebih dari 2 alamat IP, program Anda dapat bekerja 50% dari waktu, tergantung pada urutan acak OS mengembalikan alamat IP.
Mark Lakata

@ MarkLakata Saya memikirkan masalah yang sama. Fungsi dalam jawaban saya di bawah ini akan menanganinya. Anda dapat menentukan jenis antarmuka jaringan yang Anda inginkan dari alamat IP.
compman2408

3
Hanya FTR, jika Anda google di sini untuk Unity3D, itu Network.player.ipAddress di API mereka
Fattie

@MarkLakata secara tegas, IP "pertama" atau "terakhir" adalah IP "benar", karena browser dapat menggunakan IP apa pun yang tersedia. Kemungkinan koreksi yang baik adalah mengembalikan setiap IP yang terkait dengan mesin.
UncaAlby

Jawaban:


457

Untuk mendapatkan Alamat IP lokal:

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!");
}

Untuk memeriksa apakah Anda terhubung atau tidak:

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


29
tidak akan berfungsi jika Anda menggunakan hal-hal seperti kotak virtual vm, genymotion, dll.
PauLEffect

5
Setuju dengan PaulEffect. Tidak hanya metode ini buruk untuk beberapa kartu jaringan, tetapi juga, itu tidak membedakan antara alamat IP v6 dan IP v4.
Maks

16
@John AddressFamily.InterNetwork adalah IP v4 dan AddressFamily.InterNetworkV6 adalah IP v6
Leonardo Xavier

Saya Menggunakan Geraldo H Jawab, tetapi jika ada yang menggunakan ini, Anda mungkin ingin menghapus semua ips yang berakhir dengan 1, sehingga itu akan menghapus loopback dan box default virtualbox / vmware
Leonardo Xavier

6
Tampaknya Anda menggunakan VMWare atau perangkat lunak virtualisasi lainnya. OP tidak memintanya, jadi saya pikir turunkan pemungutan suara karena itu agak keras. Jika Anda memiliki VMWare atau beberapa NIC, beberapa jawaban lain sudah memberikan petunjuk untuk itu.
Mrchief

218

Ada cara yang lebih akurat ketika ada alamat multi ip yang tersedia di mesin lokal. Connectsoket UDP dan baca titik akhir lokalnya:

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

Connectpada soket UDP memiliki efek sebagai berikut: ia menetapkan tujuan untuk Send/ Recv, membuang semua paket dari alamat lain, dan - yang kami gunakan - mentransfer soket ke keadaan "terhubung", mengatur bidang yang sesuai. Ini termasuk memeriksa keberadaan rute ke tujuan sesuai dengan tabel routing sistem dan mengatur titik akhir lokal yang sesuai. Bagian terakhir tampaknya tidak terdokumentasi secara resmi tetapi sepertinya sifat integral dari Berkeley sockets API (efek samping dari keadaan "terhubung" UDP) yang bekerja dengan andal di Windows dan Linux di seluruh versi dan distribusi.

Jadi, metode ini akan memberikan alamat lokal yang akan digunakan untuk terhubung ke host jarak jauh yang ditentukan. Tidak ada koneksi nyata yang dibuat, maka ip jarak jauh yang ditentukan dapat dijangkau.


4
Ini adalah solusi terbaik yang sesuai dengan kebutuhan saya. Dalam situasi saya, saya memiliki banyak kartu jaringan dan beberapa koneksi nirkabel. Saya perlu mendapatkan alamat IP yang disukai tergantung pada koneksi mana yang diaktifkan.
David

10
Tanpa koneksi jaringan - Anda tidak memiliki alamat IP. Oleh karena itu, kode masih berlaku sebagai valid, meskipun akan lebih bijaksana untuk menambahkan try..catch untuk menangani situasi seperti itu, dan mengembalikan sesuatu seperti "127.0.0.1" jika SocketException dilempar.
Russ

2
@ PatrickSteele, ya, itu mengembalikan alamat ip keluar yang disukai untuk target tertentu. jika Anda ingin mendapatkan alamat IP LAN Anda, coba tunjukkan target untuk mendapatkan beberapa ip dari LAN Anda
Mr.Wang dari Next Door

2
Metode ini berfungsi pada mac dengan dotnet core, sedangkan jawaban yang diterima saat ini tidak.
Pelet

9
Solusi ini bekerja sekitar 4 kali lebih cepat dari jawaban yang diterima (oleh Mrchief). Ini harus menjadi jawaban yang sebenarnya
Kamarey

115

Refactoring kode Mrcheif untuk meningkatkan Linq (mis. 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);
}

:)


Saya punya beberapa Alamat IP sebagai "Inter Network" dan solusi ini benar-benar berfungsi dan memberikan yang benar kembali. Yang lain dari Tuanchief hanya memberi saya yang terakhir. Jadi sebenarnya yang ini seharusnya yang benar;)
Keenora Fluffball

26
@KeenoraFluffball - ini memberi Anda yang pertama, sedangkan yang ini memberi Anda yang terakhir (atau sebaliknya, tergantung bagaimana daftar dibuat). Either way, tidak ada yang benar - jika ada lebih dari 1 alamat IP yang diberikan kepada Anda, Anda perlu tahu jaringan mana yang Anda gunakan. Menebak dengan mengambil yang pertama atau terakhir bukanlah solusi yang benar.
gbjbaanb

Mungkin ingin juga memasukkan AddressFamily.InterNetworkV6
joelsand

kembalinya nol jika jaringan tidak tersedia tidak berguna jika Anda harus menangani PC mandiri juga. Saya menggantinya dengan "kembalikan IPAddress.Loopback;" yang sesuai dengan nomor IP khusus 127.0.0.1.
Christian

109

Saya tahu ini mungkin menendang kuda mati, tapi mungkin ini bisa membantu seseorang. Saya telah mencari di mana-mana cara untuk menemukan alamat IP lokal saya, tetapi di mana-mana saya menemukan mengatakan untuk menggunakan

Dns.GetHostEntry(Dns.GetHostName());

Saya tidak suka ini sama sekali karena hanya mendapatkan semua alamat yang diberikan ke komputer Anda. Jika Anda memiliki beberapa antarmuka jaringan (yang hampir semua komputer lakukan sekarang-a-hari), Anda tidak tahu alamat mana yang cocok dengan antarmuka jaringan mana. Setelah melakukan banyak penelitian, saya membuat fungsi untuk menggunakan kelas NetworkInterface dan menarik informasi darinya. Dengan cara ini saya bisa tahu apa jenis antarmuka itu (Ethernet, nirkabel, loopback, terowongan, dll), apakah itu aktif atau tidak, dan SOOO lebih.

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

Sekarang untuk mendapatkan alamat IPv4 dari panggilan antarmuka jaringan Ethernet Anda:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

Atau antarmuka Nirkabel Anda:

GetLocalIPv4(NetworkInterfaceType.Wireless80211);

Jika Anda mencoba untuk mendapatkan alamat IPv4 untuk antarmuka nirkabel, tetapi komputer Anda tidak memiliki kartu nirkabel yang terpasang, itu hanya akan mengembalikan string kosong. Hal yang sama dengan antarmuka Ethernet.

Semoga ini bisa membantu seseorang! :-)

EDIT:

Telah ditunjukkan (terima kasih @NasBanov) bahwa meskipun fungsi ini berfungsi untuk mengekstraksi alamat IP dengan cara yang jauh lebih baik daripada menggunakannya Dns.GetHostEntry(Dns.GetHostName())tidak baik untuk mendukung beberapa antarmuka dengan tipe yang sama atau beberapa alamat IP pada satu antarmuka. . Ini hanya akan mengembalikan satu alamat IP ketika mungkin ada beberapa alamat yang ditetapkan. Untuk mengembalikan SEMUA alamat yang ditugaskan ini, Anda cukup memanipulasi fungsi asli untuk selalu mengembalikan array alih-alih string tunggal. Sebagai contoh:

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

Sekarang fungsi ini akan mengembalikan SEMUA alamat yang ditugaskan untuk jenis antarmuka tertentu. Sekarang untuk mendapatkan hanya satu string, Anda bisa menggunakan .FirstOrDefault()ekstensi untuk mengembalikan item pertama dalam array atau, jika kosong, kembalikan string kosong.

GetLocalIPv4(NetworkInterfaceType.Ethernet).FirstOrDefault();

5
Ini adalah solusi yang lebih baik karena tidak ada kegunaan DNS di banyak tempat dan antarmuka dapat memiliki beberapa alamat ip. Saya juga menggunakan metode serupa.
Mert Gülsoy

Masalahnya adalah Anda hanya mengembalikan 1 alamat IP per antarmuka ... IP terakhir, foreach.
Nas Banov

@ compman2408 - tidak benar, satu antarmuka dapat memiliki beberapa IP, lihat en.wikipedia.org/wiki/Multihoming#Varian untuk semua kombo. Contoh yang jelas adalah ketika menjalankan IPv4 dan IPv6, tetapi di masa lalu saya memiliki adaptor ethernet tunggal yang berpartisipasi dalam beberapa jaringan IPv4. Tidak biasa mungkin - belum legal sepenuhnya. Misalnya untuk Windows, lihat windowsnetworking.com/articles-tutorials/windows-2003/…
Nas Banov

@NasBanov Fungsi ini hanya diatur untuk mendapatkan alamat IPv4 jadi saya bahkan tidak akan berbicara tentang IPv6 dan kegunaan saat ini. Saya menyadari multihoming terhubung ke beberapa jaringan pada banyak antarmuka namun belum pernah mendengar menghubungkan ke beberapa jaringan pada antarmuka yang sama. Meskipun tampaknya Anda benar bahwa itu benar-benar mungkin, <1% orang yang menggunakan NIC mereka dengan cara itu hanya perlu mengubah fungsi untuk mengembalikan array.
compman2408

1
Terima kasih untuk ini. FYI, setidaknya pada. NET 3.5 mono di OSX item.OperationalStatusselalu kembali Unknown.
GM

36

Ini adalah versi modifikasi (dari versi compman2408) yang berfungsi untuk saya:

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

Anda dapat memanggil metode ini misalnya seperti:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

Perubahan: Saya mengambil IP dari adaptor yang memiliki IP gateway yang ditugaskan untuk itu. Perubahan kedua: Saya telah menambahkan docstring dan break statement untuk membuat metode ini lebih efisien.


2
Solusi cerdas. Saya sekarang menggunakan ini.
RQDQ

4
Memiliki masalah yang sama seperti kode itu berasal: itu hanya mengembalikan salah satu IP, IP acak dari banyak - yang tidak harus menjadi yang Anda butuhkan. Ini menghasilkan ademiller.com/blogs/tech/2008/06/it-works-on-my-machine-award
Nas Banov

1
@NasBanov, Tentu saya memang mendapatkannya, karena saya menyatakan dalam posting saya: "yang bekerja untuk saya". :-)
Gerardo H

Ini jalannya, terima kasih untuk ini. Ketika Anda memiliki sakelar kembali loop untuk emulator terpasang, semua varian lainnya gagal saat yang satu ini berhasil!
DiamondDrake

1
Mengapa Anda hanya mengembalikan alamat ip terakhir yang Anda temukan, bukan yang pertama? Sederhana breakdi bagian paling dalam ifatau returnakan melakukan trik.
Martin Mulder

20

Ini adalah kode terbaik yang saya temukan untuk mendapatkan IP saat ini, menghindari host VMWare atau alamat IP tidak valid lainnya.

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

Anda mungkin harus menjelaskan, mengapa kode ini adalah solusi untuk jawabannya. Bisakah Anda benar-benar mendapatkan jawaban atas pertanyaan jika Anda terhubung ke internet dan apakah ini menghasilkan kesalahan?
Philipp M

Cara lain tidak menggunakan validasi IsDnsEligible dan PrefixOrigin.
rodcesar.santos

@ PhilippM Jika alamat bukan DNS yang Memenuhi Syarat, itu adalah IP internal yang dicadangkan. Ini bukan host penyedia internet. Dan jika PrefixOrigin disediakan oleh server DHCP, mungkin ini adalah pilihan alamat terbaik. Ini adalah fungsi unik yang berfungsi untuk saya!
rodcesar.santos

1
@ user1551843 - itu hebat, terima kasih. Saya menggunakan metode GetHostByName lama disusutkan tapi itu mengembalikan IP dari adaptor VMWare :)
Jason Newland

Ini adalah satu-satunya solusi yang bekerja untuk saya di vpn + nirkabel. Terima kasih.
jay-

12

Saya pikir menggunakan LinQ lebih mudah:

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

14
Itu bukan LINQ, itu metode ekstensi dan lambdas. Ada perbedaan.
Tandai

10
@ Mark - Jika Anda tidak menambahkan "using System.Linq;" Anda tidak dapat menggunakan metode ekstensi "Pertama"
BornToCode

5
Itu karena metode ekstensi berada di kelas Enumerable yang ada di System.Linq namespace. Itu masih bukan LINQ.
Markus

20
Mark, bahkan dalam bentuk singkat ini, pernyataan tersebut memang menggunakan LINQ-to-objek yang disajikan dengan sintaksis metode (lambda). Sintaks kueri hanyalah gula sintaksis yang dikompilasi ke rantai panggilan metode ekstensi IEnumerable, yang merupakan objek-objek LINQ. Sumber: menulis penyedia LINQ-to-SQL dan serangkaian artikel tentang masalah ini.
constantine g


9

Untuk tertawa, saya pikir saya akan mencoba dan mendapatkan pernyataan LINQ tunggal dengan menggunakan operator bersyarat nol C # 6 yang baru. Terlihat sangat gila dan mungkin sangat tidak efisien, tetapi berhasil.

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

Kesopanan logis dari Gerardo H(dan dengan referensi compman2408).


Pasti menyenangkan (+1), tetapi sebenarnya tidak perlu tidak efisien sama sekali. Mengingatkan saya pada pemrograman LISP atau Keempat :-)
Roland

6

Cara lain untuk mendapatkan IP menggunakan ekspresi LINQ:

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 Saya menemukan jawaban ini hari ini dan itu sangat berguna walaupun ia mengembalikan IP yang salah (bukan karena kode tidak berfungsi) tetapi memberikan IP internetwork yang salah ketika Anda memiliki hal-hal seperti Himachi berjalan.

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
Apakah maksud Anda Logmein Hamachi? Ini adalah solusi VPN dan mengotak-atik tumpukan jaringan. Juga, sebagai VPN, tampaknya masuk akal bahwa ia mengembalikan IP yang diberikan VPN ketika terhubung (hanya dugaan saya).
Mrchief

2
Sama sekali tidak bisa diandalkan. Bukan hanya 192.0.0.0/8bukan tes yang benar untuk alamat IP pribadi (ada 3 rentang, semuanya berbeda dari yang satu ini), bisa juga menjadi rentang jaringan perusahaan, jadi tidak terlalu "lokal".
ivan_pozdeev

5

Diuji dengan satu atau beberapa kartu LAN dan mesin Virtual

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

Ingatlah bahwa ini hanya berfungsi untuk Ethernet. Hapus pembatasan NetworkInterfaceType untuk mendukung wi-fi.
scor4er

3

Hanya versi saya yang diperbarui menggunakan LINQ:

/// <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

Prasyarat: Anda harus menambahkan referensi System.Data.Linq dan merujuknya

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

2

Saya juga kesulitan mendapatkan IP yang benar.

Saya mencoba berbagai solusi di sini tetapi tidak ada yang memberi saya pengaruh yang diinginkan. Hampir semua tes bersyarat yang disediakan menyebabkan tidak ada alamat yang digunakan.

Inilah yang bekerja untuk saya, semoga membantu ...

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 selalu kosong
aj.toulan

1

Perlu diingat, dalam kasus umum Anda dapat memiliki beberapa terjemahan NAT berlangsung, dan beberapa server dns, masing-masing beroperasi pada tingkat terjemahan NAT yang berbeda.

Bagaimana jika Anda memiliki NAT tingkat operator, dan ingin berkomunikasi dengan pelanggan lain dari operator yang sama? Dalam kasus umum Anda tidak pernah tahu pasti karena Anda mungkin muncul dengan nama host yang berbeda di setiap terjemahan NAT.


1

Sudah lenyap, ini bekerja untuk saya

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

1

Memperbarui jawaban Mrchief dengan Linq, kita akan memiliki:

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

1

Ini mengembalikan alamat dari setiap antarmuka yang memiliki alamat gateway dan alamat unicast dalam dua daftar terpisah, IPV4 dan IPV6.

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

Solusi rapi :)
Johan Franzén

1

Sudah ada banyak jawaban, tetapi saya masih memberikan salah satu jawaban saya:

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

Satu liner:

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

Catatan: Cari dari yang terakhir karena masih berfungsi setelah beberapa antarmuka ditambahkan ke perangkat, seperti MobileHotspot, VPN atau adaptor virtual mewah lainnya.


1
Jadi jika IP lokal saya 10.0.2.3 tidak ditemukan? Sangat aneh dalam kode ini.
frankhommers

@frankhommers dikatakan cek hanya untuk blok 16-bit
nyconing

Blok 16 bit juga bisa menjadi sesuatu yang lain dari 192.168
frankhommers

0

Selain itu hanya kode sederhana untuk mendapatkan Ip Klien:

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

Semoga ini bisa membantu Anda.


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

masukkan deskripsi gambar di sini


5
Jawaban Anda harus berisi deskripsi cara kerjanya untuk kasus OP dan juga untuk pembaca di masa mendatang.
Ronak Dhoot

Lebih baik untuk menyertakan penjelasan tentang jawaban Anda untuk pembaca masa depan.
Nicolas Gervais

0

Kode compman2408 yang dimodifikasi untuk dapat beralih melalui masing-masing 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;
}

Dan Anda bisa menyebutnya seperti ini:

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

Di bawah aksi yang sama

Fungsi LocalIP ()

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

txtIP.Text = Host

Kembali benar

Fungsi Akhir


Contoh di bawah ini adalah aksi yang sama Fungsi LocalIP () Dim Host As String = Dns.GetHostEntry (Dns.GetHostName) .AddressList (1) .MapToIPv4.ToString txtIP.Text = Host Mengembalikan Fungsi True End
YongJae Kim

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

satu baris kode: D


7
Ini mungkin melempar OutOfRangeException dalam beberapa kasus.
Loudenvier

5
Juga, bagaimana Anda tahu yang mana yang Anda inginkan? Apa yang tepat untuk Anda mungkin salah bagi orang lain.
Tandai

-3

Jika Anda memiliki mesin virtual atau kartu jaringan tambahan, mungkin ada nilai lain dalam daftar alamat. Saran saya adalah untuk memeriksa entri daftar alamat dan mencetak yang sesuai. Dalam entri kasus saya 3 adalah alamat ipv4 mesin saya

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

Jangan lupa menambahkan using System.Net;


1
Koreksi; Semuanya adalah alamat IP mesin Anda. Yang mana yang Anda inginkan, bagaimanapun, adalah keseluruhan cerita lain. Perhatikan bahwa pesanan dapat berubah, dan karena metode yang Anda gunakan, Anda akan selalu menebak.
Tandai

Itulah yang saya katakan, Anda harus memeriksa entri daftar alamat, dan ya itu menebak, tetapi setelah melihat semua entri, menebak tidak terlalu sulit
Bibaswann Bandyopadhyay

Bagaimana Anda tahu mana yang sesuai? Menggunakan solusi compman2048, Anda setidaknya akan tahu yang terkait dengan antarmuka mana.
Tandai

Solusi itu tidak berfungsi di komputer saya, karena saya memiliki 2 antarmuka wlan, 2 mesin virtual, dan 1 emulator, jadi saya mendapat banyak IP. Tetapi jika Anda mencari alamat internal yang disediakan oleh router akan dimulai dengan 192 atau 172 atau 10, itulah yang saya pahami
Bibaswann Bandyopadhyay

Kecuali jika router Anda membagikan IP publik, yang tidak biasa tetapi mungkin.
Tandai
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.