376

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.

Martijn
  • 11,964
  • 12
  • 50
  • 96
Tono Nam
  • 34,064
  • 78
  • 298
  • 470
  • 2
    `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? – Andy Jul 23 '11 at 20:28
  • 6
    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. – Mark Lakata Jun 23 '14 at 23:46
  • @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. – compman2408 Oct 13 '14 at 14:54
  • 3
    Just FTR, if you google here for Unity3D, it's Network.player.ipAddress in their API – Fattie Nov 21 '14 at 04:45
  • @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. – UncaAlby Feb 20 '17 at 23:34

28 Answers28

552

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

ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
Mrchief
  • 75,126
  • 20
  • 142
  • 189
  • 43
    won't work if you use stuff like vm virtual box, genymotion, etc. – PauLEffect Oct 06 '14 at 03:03
  • 6
    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. – Max Jan 09 '15 at 22:30
  • 26
    @John AddressFamily.InterNetwork is IP v4 and AddressFamily.InterNetworkV6 is IP v6 – Leonardo Xavier Jun 23 '15 at 12:42
  • 3
    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 ips – Leonardo Xavier Jun 23 '15 at 13:03
  • 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. – gman May 31 '16 at 08:27
  • 9
    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. – Mrchief May 31 '16 at 17:32
  • Can it be used to get the IP of a system accessing the network through a VPN ? – Swagat Swain Jan 12 '18 at 10:57
  • This works without VirtualBox or any interfaces that can mess with the results. @rodcesar.santos answer is really the best here. – foxtrotuniform6969 Feb 26 '18 at 19:35
  • Why this method is static? – JDo Aug 02 '18 at 06:54
  • 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. – Mrchief Aug 02 '18 at 14:43
  • For handling VMs as others have mentioned, refer to https://stackoverflow.com/questions/8089685/c-sharp-finding-my-machines-local-ip-address-and-not-the-vms/25553311 – Chad Aug 12 '19 at 20:09
  • It always get IP of VirtualBox Host ! I don't want get it. – Hieu.Gi Jan 02 '20 at 04:43
  • Save a line of code with `IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());`. – Chiramisu Sep 18 '20 at 18:33
  • 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://stackoverflow.com/a/64641294/1614903 for a solution that really gets the IP of the interface. – Holger Böhnke May 12 '21 at 16:12
  • does not work on VPS with Ubuntu Server OS – okarpov May 26 '22 at 08:51
330

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.

Mr.Wang from Next Door
  • 13,670
  • 12
  • 64
  • 97
  • 8
    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. – BeanFlicker Nov 01 '15 at 22:57
  • this is a clever workaround to weed-out most of the virtual interfaces (VM, VPN) and such – Nas Banov Mar 05 '16 at 21:09
  • 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:65530 – MrLister Aug 03 '16 at 19:50
  • 19
    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. – Russ Sep 01 '16 at 13:38
  • 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. – PatrickSteele Jan 26 '17 at 13:01
  • 4
    @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 LAN – Mr.Wang from Next Door Jan 29 '17 at 06:30
  • @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. http://tpcg.io/NCyUfR – Mr.Wang from Next Door Oct 19 '17 at 11:24
  • 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`](https://msdn.microsoft.com/en-us/library/d7ew360f(v=vs.110).aspx) nor [`connect`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms737625(v=vs.85).aspx) 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. – ivan_pozdeev Oct 19 '17 at 15:10
  • 3
    This method works on a mac with dotnet core, whereas the the accepted answer currently does not. – Pellet Dec 07 '17 at 06:09
  • 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. – FAHID Dec 19 '17 at 10:57
  • 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? – AlexC Aug 21 '18 at 19:05
  • @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` ? – Mr.Wang from Next Door Aug 22 '18 at 08:29
  • @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. – AlexC Aug 22 '18 at 16:00
  • 2
    >> 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()` – Mr.Wang from Next Door Aug 28 '18 at 05:17
  • 12
    This solution works about 4 times faster than the accepted answer (by Mrchief). This should be the real answer – Kamarey Sep 27 '18 at 10:41
  • 1
    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`? – derHugo Jun 24 '20 at 13:54
  • @derHugo 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. – Scott Brickey Apr 21 '21 at 20:48
  • 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. – GhostShaman Jul 22 '21 at 13:28
  • Works on VPS with Ubuntu Server OS, thx! – okarpov May 26 '22 at 08:54
147

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();
starball
  • 20,030
  • 7
  • 43
  • 238
compman2408
  • 2,369
  • 1
  • 15
  • 15
  • 8
    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. – Mert Gülsoy Oct 21 '14 at 15:32
  • The issue with this is that you only return 1 IP address per interface... the last IP, foreach. – Nas Banov Mar 02 '16 at 22:52
  • @compman2408 - not true, a single interface can have multiple IPs, see https://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 http://www.windowsnetworking.com/articles-tutorials/windows-2003/Understanding-Advanced-TCP-IP-Settings-Windows-2003.html – Nas Banov Mar 04 '16 at 18:44
  • @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. – compman2408 Mar 05 '16 at 07:37
  • @compman2408 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 rest – Nas Banov Mar 05 '16 at 21:00
  • @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. – compman2408 Mar 10 '16 at 05:23
  • 1
    Thank you for this. FYI, at least on .NET 3.5 mono on OSX `item.OperationalStatus` always returns `Unknown`. – gman May 31 '16 at 08:43
  • 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? – Emperor Eto Apr 08 '22 at 15:50
  • 1
    @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). – compman2408 Apr 22 '22 at 05:55
120

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

:)

Ben Baron
  • 14,496
  • 12
  • 55
  • 65
Pure.Krome
  • 84,693
  • 113
  • 396
  • 647
  • 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 ;) – Keenora Fluffball Dec 22 '11 at 12:23
  • 32
    @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. – gbjbaanb Sep 04 '13 at 09:11
  • May want to also include AddressFamily.InterNetworkV6 – joelsand Mar 19 '19 at 18:41
  • 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. – Christian Nov 22 '19 at 14:10
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.

YetAnotherDuck
  • 294
  • 4
  • 13
Gerardo H
  • 694
  • 6
  • 9
  • 4
    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 http://www.ademiller.com/blogs/tech/2008/06/it-works-on-my-machine-award/ – Nas Banov Mar 05 '16 at 21:14
  • 1
    @NasBanov, Sure I did earn it, as I'm stating in my post: "which worked for me". :-) – Gerardo H Apr 21 '16 at 16:40
  • 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! – DiamondDrake Aug 27 '16 at 16:02
  • 1
    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. – Martin Mulder May 10 '17 at 09:23
  • Best answer! **Working fine in 2021.** Thank you so much :) – Shariful Islam Mubin May 26 '21 at 17:06
28

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()
        : "";
}
rodcesar.santos
  • 388
  • 4
  • 4
  • 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? – Philipp M Nov 10 '16 at 13:52
  • The other ways does not use IsDnsEligible and PrefixOrigin validation. – rodcesar.santos Dec 05 '16 at 11:50
  • @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! – rodcesar.santos Dec 05 '16 at 11:57
  • 1
    @user1551843 - that was great, thanks. I was using the old depreciated GetHostByName method but it was returning the IP of a VMWare adapter :) – Jason Newland Jan 15 '17 at 03:04
  • This was the only solution that worked for me on vpn + wireless. Thank you. – jay-danger Nov 02 '18 at 21:02
  • Thanks for this. It actually gets the local IP assigned by the router, unlike other solutions. – mihaiconst Apr 08 '21 at 07:01
25

I think using LINQ is easier:

Dns.GetHostEntry(Dns.GetHostName())
   .AddressList
   .First(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
   .ToString()
Kapé
  • 4,411
  • 3
  • 37
  • 54
  • 1
    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. – Matt Apr 27 '20 at 11:11
  • @Matt 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`. – Kapé Dec 21 '20 at 09:25
  • 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 ...}` – Matt Dec 21 '20 at 09:56
  • 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. – Matt Dec 21 '20 at 11:56
11

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();
}
jps
  • 20,041
  • 15
  • 75
  • 79
Amirhossein Yari
  • 2,054
  • 3
  • 26
  • 38
10

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

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

Stajs
  • 1,255
  • 11
  • 21
  • 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 so that "FirstOrDefault() ?? string.Empty" is sufficient. – user2864740 Jul 31 '20 at 17:44
  • 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". – Stajs Aug 01 '20 at 21:45
  • 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 `.UnicastAddresses` – Garr Godfrey Jan 20 '22 at 17:23
10

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;
    }
Shanewaj
  • 2,078
  • 1
  • 20
  • 16
  • Keep in mind that this one is working for Ethernet only. Remove NetworkInterfaceType restriction to support wi-fi. – scor4er Aug 06 '19 at 19:07
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;
}
Ahmad Ahmadi
  • 337
  • 1
  • 4
  • 19
Jordan Trainor
  • 2,410
  • 5
  • 21
  • 23
  • 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). – Mrchief Jan 28 '13 at 22:17
  • 2
    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". – ivan_pozdeev Oct 17 '17 at 19:47
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;
}
StuiterSlurf
  • 2,464
  • 4
  • 34
  • 55
Giusepe
  • 655
  • 5
  • 15
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);
UberBiza
  • 83
  • 6
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));
pola
  • 509
  • 4
  • 8
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)

  • 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. – Holger Böhnke May 12 '21 at 16:17
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;
}
Ashkan S
  • 10,464
  • 6
  • 51
  • 80
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());
}
Michael Jordan
  • 382
  • 2
  • 13
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();
ScottJShea
  • 7,041
  • 11
  • 44
  • 67
Naimish Mungara
  • 213
  • 1
  • 4
  • 14
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.

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;
}
Sourcephy
  • 239
  • 4
  • 4
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
Caius Jard
  • 72,509
  • 5
  • 49
  • 80
  • 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 Function – YongJae Kim May 23 '20 at 07:16
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.

Majedur
  • 3,074
  • 1
  • 30
  • 43
  • 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. – Trevor Apr 02 '21 at 16:16
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"}");
    }
}
Najeeb
  • 313
  • 1
  • 5
  • 19
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());
Adamy
  • 2,789
  • 3
  • 27
  • 25
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();
    }
Manne M
  • 1
  • 1
  • 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? – Jeremy Caney Aug 19 '23 at 01:02
-1
Dns.GetHostEntry(Dns.GetHostName()).AddressList[1].MapToIPv4() //returns 192.168.14.1

enter image description here

Eran Peled
  • 767
  • 6
  • 6
-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.

nyconing
  • 1,092
  • 1
  • 10
  • 33
-2

This is the shortest way:

Dns.GetHostEntry(
    Dns.GetHostName()
).AddressList.AsEnumerable().Where(
    ip=>ip.AddressFamily.Equals(AddressFamily.InterNetwork)
).FirstOrDefault().ToString()
mousetail
  • 7,009
  • 4
  • 25
  • 45