Okay, this is a really short article, but I felt the need to write this because too many people seem to take the wrong way.

Problem

First: getting the external IP address of a machine shouldn’t be done locally (Dns.GetHostAddresses(Dns.GetHostName()) <- this is evil).

Why?

This method is good only if you need the local IP address. If you need the external one consider that not every machine is directly connected to the internet. Some might be sitting behind a firewall or a router, but the framework won’t know it, so it will return the local IP address instead of the external one.

Solution

One reliable way to solve this is to ask a website what’s your external IP address - there are many websites that can be used for this and some of them will even return your IP address as a plain text - which is nice.

Here’s a short example of how you should do it (don’t forget to include System.Net):

  • this snippet should only give you the idea of how to do this, don’t use it as it is.
1
2
3
4
5
6
7
string getExternalIP()
{
    using (WebClient client = new WebClient())
    {
         return client.DownloadString("http://canihazip.com/s");
    }
}

What if the website is down?

Well, this is a risk that can be avoided by using…more websites :) and a bunch of try-catch blocks. If a website can’t be reached, we query the next one. Simple as that.

A more reliable example here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
string getExternalIP()
{
    using (WebClient client = new WebClient())
    {
        try
        {
            return client.DownloadString("http://canihazip.com/s");
        }
        catch (WebException e)
        {
            // this one is offline
        }

        try
        {
            return client.DownloadString("http://wtfismyip.com/text");
        }
        catch (WebException e) 
        {  
            // offline...
        }

        try
        {
            return client.DownloadString("http://ip.telize.com/");
        }
        catch (WebException e)
        {
            // offline too...
        }

        // if we got here, all the websites are down, which is unlikely
        return "Check internet connection?";
    }
}

It can still be improved by doing all the connections at the same time (putting each one in a different thread) - this will reduce the waiting time (if the first websites are down).

However these modifications would exceed the purpose of the article.