Get local IP address
Asked Answered
F

28

389

In the internet there are several places that show you how to get an IP address. And a lot of them look like this example:

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

With this example I get several IP addresses, but I'm only interested in getting the one that the router assigns to the computer running the program: the IP that I would give to someone if he wishes to access a shared folder in my computer for instance.

If I am not connected to a network and I am connected to the internet directly via a modem with no router then I would like to get an error. How can I see if my computer is connected to a network with C# and if it is then to get the LAN IP address.

Foulness answered 23/7, 2011 at 20:20 Comment(5)
If I am not connected to a network and I am connected to the internet This statement seems contradictory. Are you trying to figure out if your computer is connected to a private LAN or the Internet?Ellswerth
Just as a warning: A computer can have more than one IP interface, for example a LAN and WiFi. If you bind a service to a particular piece of hardware (say the LAN), you need the IP of the LAN. Most of the following examples will return the "first" or "last" IP address found. If you have more than 2 IP address, your program may work 50% of the time, depending on the random order the OS returns the IP addresses.Empirin
@MarkLakata I thought of the same issue. The function in my answer below will handle it. You can specify which type of network interface you want the IP address from.Slowworm
Just FTR, if you google here for Unity3D, it's Network.player.ipAddress in their APIPassementerie
@MarkLakata strictly speaking, the "first" or "last" IP is the "correct" IP, as the browser may use any IP that is available. Likely a good correction should be to return every IP associated with the machine.Tannate
F
563

To get local Ip Address:

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

To check if you're connected or not:

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

Forenamed answered 23/7, 2011 at 20:26 Comment(16)
won't work if you use stuff like vm virtual box, genymotion, etc.Fere
Agree with PaulEffect. Not only this method is bad for multiple network card, but also, it's not differentiating between IP v6 and IP v4 addresses.Moynahan
@John AddressFamily.InterNetwork is IP v4 and AddressFamily.InterNetworkV6 is IP v6Guardrail
I'm Using Geraldo H Answer, but if anyone is using this, you may want to remove all ips that ends with 1, so it will remove loopback and virtualbox/vmware default ipsGuardrail
This doesn't work for me. I get 3 ip addresses on my machine, one for en0, one for vmnet1 and another for vmnet8. None of the data provided by this example lets be distinguish between them.Imprecation
It seems you're using VMWare or other virtualization software. The OP did not ask for that, so I think down voting due to that is a bit harsh. If you have VMWare or multiple NICs, some of the other answers already provide clues to that.Forenamed
Can it be used to get the IP of a system accessing the network through a VPN ?Propose
This works without VirtualBox or any interfaces that can mess with the results. @rodcesar.santos answer is really the best here.Lemuel
Why this method is static?Turpitude
Because it requires no state; and all other things being equal, static methods gives you a slightly better performance (may not make any noticeable difference in a real world or large code base). In the end, you could make it an instance method if you prefer to.Forenamed
For handling VMs as others have mentioned, refer to #8090185Virgy
It always get IP of VirtualBox Host ! I don't want get it.Docent
Save a line of code with IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());.Ludmilla
This might work in most cases, but it does not get the IP address configured on a local interface. It asks some DNS server to provide the IP of any host which accidently has the same name as the local one. These two are fundamentally different. See below answer https://mcmap.net/q/86770/-get-local-ip-address for a solution that really gets the IP of the interface.Bus
does not work on VPS with Ubuntu Server OSJacie
not working in blazor serverExhibitionist
B
342

There is a more accurate way when there are multi ip addresses available on local machine. Connect a UDP socket and read its local endpoint:

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

Connect on a UDP socket has the following effect: it sets the destination for Send/Recv, discards all packets from other addresses, and - which is what we use - transfers the socket into "connected" state, settings its appropriate fields. This includes checking the existence of the route to the destination according to the system's routing table and setting the local endpoint accordingly. The last part seems to be undocumented officially but it looks like an integral trait of Berkeley sockets API (a side effect of UDP "connected" state) that works reliably in both Windows and Linux across versions and distributions.

So, this method will give the local address that would be used to connect to the specified remote host. There is no real connection established, hence the specified remote ip can be unreachable.

Backside answered 9/12, 2014 at 10:13 Comment(21)
This is the best solution that worked for my needs. In my situation I have many networks card and a few wireless connections. I needed to get the preferred IP address depending on which connection was activated.Intinction
this is a clever workaround to weed-out most of the virtual interfaces (VM, VPN) and suchTheca
This only works if you have an active network connection.. .try booting up your laptop without a network connection and then run the code : System.Net.Sockets.SocketException (0x80004005): A socket operation was attempted to an unreachable network 10.0.2.4:65530Margalit
Without a network connection--you have no IP address, anyhow. Therefore, the code still holds as valid, though it would be prudent to add a try..catch in order to handle such a situation, and return something like "127.0.0.1" if a SocketException were thrown.Granniah
Please note that this method can produce different results depending on what address you pass to socket.Connect(). In addition to my internet connection, I have two VPN clients installed. If the address I pass to socket.Connect() is a public internet address (like "google.com"), then I get the IP address of my "main" network connection. However, if I happen to use an address that is inside the range of one of my VPN clients, then I get the IP address assigned to that VPN connection.Pindus
@PatrickSteele, yep, it returns the preferred outbound ip address for the specific target. if you want to obtain your LAN ip address, try to indicate the target to be some ip from your LANBackside
@ivan_pozdeev do you really try the code? you can try the code and change the ip address to any one not reachable. it works. tpcg.io/NCyUfRBackside
I didn't notice this is a UDP socket. I never knew it was even legal to call connect for a UDP socket. Neither Socket.Connect nor connect document the effect you're using. So, at the very least, this effect should be described in the explanation text and how much you can rely on it. That said, the current explanation text is blatantly wrong: connect on a UDP socket does not actually try to connect.Fingered
This method works on a mac with dotnet core, whereas the the accepted answer currently does not.Dickinson
Best Solution, I have Docker/VM installed and these tools install some dummy network adapters, But for my deployment I needed only the Main 1 with Communication enable.Catto
I'm having a problem with this solution: I have the computer connected to the internet, I run the code, and it works, it returns my IP address. BUT, if I disconnect the computer from the internet, and run the code AGAIN, while disconnected from the internet, it will still return my last IP Address, instead of throwing an error, as it should. Anyone else experiencing the same?Flamenco
@AlexC, this manner works no matter if you are connected to Internet. When you are disconnected, do you see the IP address form ipconfig /all or ip addr ?Backside
@Mr.Wang from Next Door , no, it says "Media Disconnected". Just try to reproduce it. Connect your laptop to wireless (and to wireless only, no ethernet cable). Run the code. It will give you the IP Address. Disable the wireless adapter. Run the code again. It will return you the last IP address, even though you are now totally disconnected from the internet.Flamenco
>> you are now totally disconnected from the internet. @AlexC, this approach returns the local IP address which is supposed to be used when accessing the specific remote ip address. From your description, what you need is not GetLocalIP(), what you need is IsSomethingReachable()Backside
This solution works about 4 times faster than the accepted answer (by Mrchief). This should be the real answerGlorious
This method requires to have an internet connection though ... what would you use in a local network where you don't know who is the Gateway or what to connect to instead of Google's 8.8.8.8?Milburr
@Milburr if the computer in question has no gateway, then whether it has 1 or 28 network adapters, and whether those adapters have 1 or 96 IP bindings, the question is still the same - which IP address do you want to use... the answer is "whichever Windows will use to connect to [destination]"... in the case of 8.8.8.8 with local only, it won't matter since none will connect - pick one or pick loopback and be done... but those IPs and NICs might be chosen differently if they're going to different remote offices, so it's context specific.Agrarian
I used this on .net core 5.0 that is running on our raspberry pi, and it worked. I tried the accepted answer (and other variations of it) and it didnt work.Magistral
Works on VPS with Ubuntu Server OS, thx!Jacie
not working in blazor serverExhibitionist
Did anyone else verify what @Flamenco was saying. I’m facing the same issueInjured
S
152

I know this may be kicking a dead horse, but maybe this can help someone. I have looked all over the place for a way to find my local IP address, but everywhere I find it says to use:

Dns.GetHostEntry(Dns.GetHostName());

I don't like this at all because it just gets all the addresses assigned to your computer. If you have multiple network interfaces (which pretty much all computers do now-a-days) you have no idea which address goes with which network interface. After doing a bunch of research I created a function to use the NetworkInterface class and yank the information out of it. This way I can tell what type of interface it is (Ethernet, wireless, loopback, tunnel, etc.), whether it is active or not, and SOOO much more.

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

Now to get the IPv4 address of your Ethernet network interface call:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

Or your Wireless interface:

GetLocalIPv4(NetworkInterfaceType.Wireless80211);

If you try to get an IPv4 address for a wireless interface, but your computer doesn't have a wireless card installed it will just return an empty string. Same thing with the Ethernet interface.

EDIT:

It was pointed out (thanks @NasBanov) that even though this function goes about extracting the IP address in a much better way than using Dns.GetHostEntry(Dns.GetHostName()) it doesn't do very well at supporting multiple interfaces of the same type or multiple IP addresses on a single interface. It will only return a single IP address when there may be multiple addresses assigned. To return ALL of these assigned addresses you could simply manipulate the original function to always return an array instead of a single string. For example:

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

Now this function will return ALL assigned addresses for a specific interface type. Now to get just a single string, you could use the .FirstOrDefault() extension to return the first item in the array or, if it's empty, return an empty string.

GetLocalIPv4(NetworkInterfaceType.Ethernet).FirstOrDefault();
Slowworm answered 17/7, 2014 at 21:41 Comment(10)
This is a better solution because there is no DNS usability in lots of places and interfaces can have multiple ip addresses. I also utilise a similar method.Mart
The issue with this is that you only return 1 IP address per interface... the last IP, foreach.Theca
@Slowworm - not true, a single interface can have multiple IPs, see en.wikipedia.org/wiki/Multihoming#Variants for all the combos. Obvious example is when running both IPv4 and IPv6, but in the past i have had single ethernet adapter participate in multiple IPv4 networks. Unusual maybe - yet perfectly legal. E.g. for Windows see windowsnetworking.com/articles-tutorials/windows-2003/…Theca
@NasBanov This function is only set up to get IPv4 addresses so I'm not even going to talk about IPv6 and its current uselessness. I'm aware of multihoming as connecting to multiple networks on multiple interfaces however have never heard of connecting to multiple networks on the same interface. Even though it seems you're correct that it is actually possible, the <1% of people using their NIC that way would just have to change the function to return an array instead.Slowworm
@Slowworm so we agree there is an issue :). Not to forget the case when there is >1 interfaces of the same kind, like 2+ physical Ethernet cards or what often is the case, virtual interfaces from VMs and VPNs? You should rename it to GetRandomLocalIPv4() or always return array and leave it at caller's peril to use .first() and ignore the restTheca
@NasBanov we only partially have an agreement. Ha. I'm not going to say this function has an issue as it was intended to return just a single IP address which is what it does (kind of like the accepted answer above).It just goes about it in a much better way. I'll still edit my answer though to add a function that supports multiple NICs of the same type or multiple IPs on the same interface.Slowworm
Thank you for this. FYI, at least on .NET 3.5 mono on OSX item.OperationalStatus always returns Unknown.Imprecation
Will this (or any method) tell you which adapters are actually connected to the network? For instance if you have both wifi and wired internet on a laptop, sometimes you'll be on one or the other - can this method determine which is actually connected so you can return the most relevant one?Graduation
@PeterMoore IIRC that's what the item.OperationalStatus == OperationalStatus.Up part does. If the NIC is in OperationalStatus.Up it's connected to a network and able to send data packets. This doesn't test connection to the internet however. Just that it's connected to a network. Also this function (as it's written) only looks at one type of NIC. It doesn't look at all NICs on a computer to return the "most relevant" IP address. It will return an IP address assigned to the type of NIC that was passed in via the function's argument (if there is one).Slowworm
not working in blazor serverExhibitionist
B
121

Refactoring Mrcheif's code to leverage Linq (ie. .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);
}

:)

Bromley answered 21/8, 2011 at 23:25 Comment(4)
I've got a few IP Addresses as "Inter Network" an this solution actually works and gives the right one back. The other one from Mrchief just gives me the last one. So actually this one should be the right one ;)Cuyp
@KeenoraFluffball - this one gives you the first one, whereas this one gives you the last one (or vice versa, depends how the list is constructed). Either way, neither is right - if there are more than 1 IP address given to you, you need to know which network you're using. Guessing by taking the first or last is not the correct solution.Schaffner
May want to also include AddressFamily.InterNetworkV6Conics
the return of null if the network is not available is not useful if you have to handle standalone PCs as well. I replaced it with "return IPAddress.Loopback;" which corresponds to the special IP number 127.0.0.1.Sheena
E
47

Here is a modified version (from compman2408's one) which worked for me:

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

You can call this method for example like:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

The change: I'm retrieving the IP from an adapter which has a gateway IP assigned to it. Second change: I've added docstrings and break statement to make this method more efficient.

Ellsworth answered 20/2, 2015 at 3:39 Comment(5)
Has the same issue like the code it was derived from: it just returns one of the IPs, a random IP from many - which does not have to be the one you need. It earns the ademiller.com/blogs/tech/2008/06/it-works-on-my-machine-awardTheca
@NasBanov, Sure I did earn it, as I'm stating in my post: "which worked for me". :-)Ellsworth
This is the way to go, thank you for this. When you have loop back switches for emulators installed, all the other variants fail while this one succeeds!Multiplicate
Why do you only return the last ip-address you have found, not the first? A simpel break in the most inner if or a return would do the trick.Teacup
Best answer! Working fine in 2021. Thank you so much :)Trivia
L
29

This is the best code I found to get the current IP, avoiding get VMWare host or other invalid IP address.

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()
        : "";
}
Laburnum answered 10/11, 2016 at 13:27 Comment(6)
You should probably explain, why this code is the solution for the answer. Can you actually get an answer on the question if you're connected to the internet and does this result in an error?Patagium
The other ways does not use IsDnsEligible and PrefixOrigin validation.Laburnum
@PhilippM If address is not a DNS Eligible, it is a reserved internal IP. It is not the internet provider host. And if PrefixOrigin was suplied by a DHCP server, possible this is the best address choice. This is the unique function that works to me!Laburnum
@user1551843 - that was great, thanks. I was using the old depreciated GetHostByName method but it was returning the IP of a VMWare adapter :)Clare
This was the only solution that worked for me on vpn + wireless. Thank you.Grenadine
Thanks for this. It actually gets the local IP assigned by the router, unlike other solutions.Eventual
C
25

I think using LINQ is easier:

Dns.GetHostEntry(Dns.GetHostName())
   .AddressList
   .First(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
   .ToString()
Closefitting answered 25/3, 2014 at 17:23 Comment(4)
Apart from that discussion, it is working fine for me. I'd like to suggest to replace . by ?., .First by ?.FirstOrDefault and append ??"" at the end - this way you can safely use it without null exceptions - if IP can't be retrieved, it will just return an empty string.Manymanya
@Manymanya Returning an empty string can give unexpected results elsewhere in your code, but I think you won't get a NRE anyway since .First will throw an exception already. But indeed depending on your use case you could use .FirstOrDefault instead and check for null.Moldboard
Indeed, it is not necessary to append ??"", that depends on the use case. But this will assign null which you can check easily if the IP couldn't be obtained: var ip = Dns?.GetHostEntry(Dns.GetHostName())?.AddressList?.FirstOrDefault(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)?.ToString(); so you won't get a NRE - you can just go ahead with if (ip != null) { ... // IP iwas obtained ...}Manymanya
I think the relevant question is: Do you want an exception to be thrown? Or rather stay in line with the code (exceptions usually "jump" to a place where the logic of your code gets lost) and rather do checks along the flow? Regarding .First() - I experienced that this can also throw unwanted exceptions, so wherever possible, I am using .FirstOrDefault() instead. Another question is: At which level of depth in the code do you want to catch exceptions? Do you re-throw them or handle them in place? And in addition: Usually, if-statements are better readable by others.Manymanya
M
11

For a laugh, thought I'd try and get a single LINQ statement by using the new C# 6 null-conditional operator. Looks pretty crazy and probably horribly inefficient, but it works.

private string GetLocalIPv4(NetworkInterfaceType type = NetworkInterfaceType.Ethernet)
{
    // Bastardized from: https://mcmap.net/q/86770/-get-local-ip-address.

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

Logic courtesy of Gerardo H (and by reference compman2408).

Manpower answered 10/2, 2016 at 3:53 Comment(3)
So .. not what I would write. This sort of odd "?." chained LINQ-to-Objects can be rewritten (or "fixed") when using Select/SelectMany (SelectMany can increase or reduce the length) to do transforms, such that the final form is IEnumeable<string> so that "FirstOrDefault() ?? string.Empty" is sufficient.Eyelash
I'm not sure you can argue the null conditional operator is "odd", but sure I take it this code is (as I said) "pretty crazy".Manpower
Once you use the first null conditional, they should all have it after that. If no network interfaces match it will throw null pointer exception on .UnicastAddressesTerpsichore
H
11

Tested with one or multiple LAN cards and Virtual machines

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;
    }
Heptad answered 5/10, 2018 at 5:5 Comment(1)
Keep in mind that this one is working for Ethernet only. Remove NetworkInterfaceType restriction to support wi-fi.Furious
I
10

Other way to get IP using linq expression:

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();
}
Impetus answered 28/5, 2017 at 11:31 Comment(0)
B
7

@mrcheif I found this answer today and it was very useful although it did return a wrong IP (not due to the code not working) but it gave the wrong internetwork IP when you have such things as Himachi running.

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;
}
Boffin answered 23/11, 2012 at 16:53 Comment(2)
Do you mean Logmein Hamachi? It is a VPN solution and it tinkers with the network stack. Also, being a VPN, it seems reasonable that it returns the VPN assigned IP when connected (just my guess).Forenamed
Completely Unreliable. Not only is 192.0.0.0/8 not a correct test for a private IP address (there are 3 ranges, all different from this one), it can be well be a corporate network range, so not so much "local".Fingered
S
5

Just an updated version of mine using 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;
}
Scrummage answered 21/9, 2015 at 18:31 Comment(0)
D
4

I also was struggling with obtaining the correct IP.

I tried a variety of the solutions here but none provided me the desired affect. Almost all of the conditional tests that was provided caused no address to be used.

This is what worked for me, hope it helps...

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);
Daisydaitzman answered 5/6, 2018 at 18:12 Comment(0)
N
3

Pre requisites: you have to add System.Data.Linq reference and refer it

using System.Linq;
string ipAddress ="";
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
ipAddress = Convert.ToString(ipHostInfo.AddressList.FirstOrDefault(address => address.AddressFamily == AddressFamily.InterNetwork));
Nashua answered 17/5, 2016 at 10:26 Comment(0)
C
3

Using these:

using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Linq;

You can use a series of LINQ methods to grab the most preferred IP address.

public static bool IsIPv4(IPAddress ipa) => ipa.AddressFamily == AddressFamily.InterNetwork;

public static IPAddress GetMainIPv4() => NetworkInterface.GetAllNetworkInterfaces()
.Select((ni)=>ni.GetIPProperties())
.Where((ip)=> ip.GatewayAddresses.Where((ga) => IsIPv4(ga.Address)).Count() > 0)
.FirstOrDefault()?.UnicastAddresses?
.Where((ua) => IsIPv4(ua.Address))?.FirstOrDefault()?.Address;

This simply finds the first Network Interface that has an IPv4 Default Gateway, and gets the first IPv4 address on that interface. Networking stacks are designed to have only one Default Gateway, and therefore the one with a Default Gateway, is the best one.

WARNING: If you have an abnormal setup where the main adapter has more than one IPv4 Address, this will grab only the first one. (The solution to grabbing the best one in that scenario involves grabbing the Gateway IP, and checking to see which Unicast IP is in the same subnet as the Gateway IP Address, which would kill our ability to create a pretty LINQ method based solution, as well as being a LOT more code)

Convergence answered 2/11, 2020 at 7:20 Comment(1)
This solution gets the real IP configured on the interface. Most DNS based solutions just ask someone else (the DNS) what it thinks the local IP might be.Bus
A
2

Updating Mrchief's answer with Linq, we will have:

public static IPAddress GetLocalIPAddress()
{
   var host = Dns.GetHostEntry(Dns.GetHostName());
   var ipAddress= host.AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
   return ipAddress;
}
Aleece answered 26/2, 2018 at 8:39 Comment(0)
V
2

This returns addresses from any interfaces that have gateway addresses and unicast addresses in two separate lists, IPV4 and 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());
}
Valona answered 8/9, 2019 at 2:38 Comment(0)
B
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();
Bertram answered 23/6, 2014 at 4:56 Comment(1)
str is always emptyIndophenol
O
1

Keep in mind, in the general case you could have multiple NAT translations going on, and multiple dns servers, each operating on different NAT translation levels.

What if you have carrier grade NAT, and want to communicate with other customers of the same carrier? In the general case you never know for sure because you might appear with different host names at every NAT translation.

Ojibwa answered 1/7, 2015 at 11:25 Comment(0)
O
1

Obsolete gone, this works to me

public static IPAddress GetIPAddress()
{ 
 IPAddress ip = Dns.GetHostAddresses(Dns.GetHostName()).Where(address => 
 address.AddressFamily == AddressFamily.InterNetwork).First();
 return ip;
}
Obtain answered 23/12, 2017 at 1:16 Comment(0)
H
1
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

Below same action

Function LocalIP()

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

   txtIP.Text = Host

   Return True

End Function
Hateful answered 22/5, 2020 at 22:45 Comment(1)
Below example is same action Function LocalIP() Dim Host As String = Dns.GetHostEntry(Dns.GetHostName).AddressList(1).MapToIPv4.ToString txtIP.Text = Host Return True End FunctionHateful
T
0

In addition just simple code for getting Client Ip:

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

Hope it's help you.

Toluol answered 23/7, 2019 at 4:37 Comment(1)
This is relevant if you have HttpContext to hand but in some cases we will not so there should be an alternative solution for that.Motivity
A
0

Modified compman2408's code to be able to iterate through each 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;
}

And you can call it like so:

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"}");
    }
}
Arguable answered 26/3, 2020 at 16:30 Comment(0)
W
0

I failed to get the IP address with the suggested answer using "var host = Dns.GetHostEntry(Dns.GetHostName())" on Debian 10 arm64, it gives an ExtendedSocketException like this

Unhandled exception. System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (00000005, 0xFFFDFFFF): Name or service not known at System.Net.Dns.GetHostEntryOrAddressesCore(String hostName, Boolean justAddresses, AddressFamily addressFamily, ValueStopwatch stopwatch) at System.Net.Dns.GetHostEntry(String hostNameOrAddress, AddressFamily family) at System.Net.Dns.GetHostEntry(String hostNameOrAddress)

I eventually got it working with System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()

var netInterfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
foreach (var netInterface in netInterfaces)
    foreach(var ip in netInterface.GetIPProperties().UnicastAddresses)
        Console.WriteLine("\t{0}", ip.Address.ToString());
Wacky answered 28/3, 2023 at 23:17 Comment(0)
M
0
    private static string GetIpAdressForLocalHost(string host)

    {
        //check if hostname is localhost or 127.0.0.1 and so on
        if(!Dns.GetHostAddresses(host).Where(IPAddress.IsLoopback).IsNullOrEmpty())
        {
            //returns the ip address for the physical network interface
            return NetworkInterface.GetAllNetworkInterfaces()
                .Where(u => (u.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || u.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
                            && u.OperationalStatus == OperationalStatus.Up && !u.GetIPProperties().GatewayAddresses.IsNullOrEmpty())
                .Select(i => i.GetIPProperties().UnicastAddresses).SelectMany(u => u).Where(u => u.Address.AddressFamily == AddressFamily.InterNetwork)
                .Select(i => i.Address.ToString()).FirstOrDefault(Dns.GetHostAddresses(host).Select(i => i.ToString()).FirstOrDefault(host));
        }
        else
            return Dns.GetHostName();
    }
Mellie answered 17/8, 2023 at 8:26 Comment(1)
Thank you for your interest in contributing to the Stack Overflow community. This question already has quite a few answers—including one that has been extensively validated by the community. Are you certain your approach hasn’t been given previously? If so, it would be useful to explain how your approach is different, under what circumstances your approach might be preferred, and/or why you think the previous answers aren’t sufficient. Can you kindly edit your answer to offer an explanation?Backgammon
D
-1
Dns.GetHostEntry(Dns.GetHostName()).AddressList[1].MapToIPv4() //returns 192.168.14.1

enter image description here

Depressed answered 8/3, 2020 at 9:32 Comment(3)
Your answer should contain a description of how it works for the case of OP and also for future readers.Gas
It's better to include an explanation of your answer for future readers.Coolant
It may throw an OutOfRangeException in some cases.Matutinal
H
-1

This is the shortest way:

Dns.GetHostEntry(
    Dns.GetHostName()
).AddressList.AsEnumerable().Where(
    ip=>ip.AddressFamily.Equals(AddressFamily.InterNetwork)
).FirstOrDefault().ToString()
Harlotry answered 17/10, 2021 at 16:24 Comment(1)
Please edit your post to include an explanationWideeyed
P
-2

There is already many of answer, but I m still contributing mine one:

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

One liner:

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

note: Search from last because it still worked after some interfaces added into device, such as MobileHotspot,VPN or other fancy virtual adapters.

Poor answered 18/10, 2019 at 13:42 Comment(3)
So if my local IP is 10.0.2.3 it's not found? That's really weird in this code.Monadelphous
@Monadelphous been said check only for 16-bit blockPoor
16 bits blocks can also be something else than 192.168Monadelphous

© 2022 - 2024 — McMap. All rights reserved.