Introduction
Geolocation is useful, but there are right ways and wrong ways to get it and to use it. The right way is to use a GPS device - but I don't know of any desktop device which needs or has one, and mobile devices generally make it difficult to access via the internet. For some reason people seem to want random websites not to know where they are... :laugh:
The problem is that an IP address has a physical location - and it must be easy to get, yes?
Background
Yes, it's easy - I'll even share the code with you in a minute - but it's also completely useless. Why? Because the physical location of an IP address is not the physical location of the client: it's the location of the internet point of presence the client is using: normally their ISP's local "office" or similar.
Let's look at the background: There are two types of IP address we are interested in - Static and Dynamic.
A Static IP is one that does not change under any circumstances: if you are disconnected completely from the internet when you reconnect you will always have the same IP address. Usually, you have to pay extra for this.
A Dynamic IP is assigned when you connect, and lasts only for the lifetime of the connection. If you disconnect your router from the phone line, you will get a different IP address when you plug it back in. These are the default for domestic connections - which are most of them!
Static IP Geolocation
Static IP's don't change, so the physical location data will also never change. So let's look at an example - Codeproject.com.. It uses a Static IP, which is 65.39.148.34 (You can find this by doing a Reverse DNS on Codeproject.com) so we can look at its physical location pretty easily:
Estimated location:
IP |
65.39.148.34 |
Country |
United States |
Region |
New York |
City |
New York |
Zip code |
10004 |
Latitude and Longitude |
40.6888 -74.0203 |
Area and Metro codes |
212 501 |
(Information from FreeGeoIP.net)
Hang on a moment... let's look at that:

But Codeproject is Canadia - it's in Toronto:

But the physical info relates to a company in New York, a different country all together, because they use a company there to handle the actual connection to the internet (which is very, very normal indeed).
Dynamic IP Geolocation
Dynamic addresses are surprisingly more accurate, but in a way, that's a lot worse!
When you connect via a router, the router and the ISP do a fair amount of negotiating: and one of the items they decide on is the IP address you will use. The ISP draws a free IP from its "local pool" of IPs - those that are assigned to your "local" area - if one is available, but if they are all in use then it looks further afield. This means that (if you live or work in a city) you will normally get an IP that is registered within a couple of miles of you, maybe even less. But...it could be hundreds of miles away:

Normally I get Swansea based IPs - it's about 30Km away or so. But this is my current, and as you can see it's London based - 250Km away. But I've had ones based in Germany in the past, where the national language is different, they are in a different time zone, and use a different currency.
So the physical location you get might be close and fairly accurate - but it's just as likely to be wildly inaccurate and:
- You can't tell which.
- The client doesn't even know where it is telling you he is.
So is there any point in looking? No - not really, because you can't rely on the information you get back!
But, getting it is simple.
I recently had a problem with my home internet connection, so I threw together some software to let me monitor my IP and when it changed - so I had to get it, which is slightly complex because you have to ask the outside world what it is - you PC doesn't need to know, and querying your router depends on the make and model.
So I used FreeGeoIP which returns your IP address as CSV data, along with the physical information. Because I prefer to "do it properly" even with quick and dirty apps, I created a class called MyIPInfo to hold it all, and a method to fill the instance:
private void FillInDetails(string host)
{
Timestamp = DateTime.Now;
IPAddress addr = IPAddress.None;
try
{
using (WebClient wc = new WebClient())
{
if (string.IsNullOrWhiteSpace(host))
{
host = "http://freegeoip.net/csv";
}
else
{
host = string.Format("http://freegeoip.net/csv{0}{1}", "/", host);
}
string data = wc.DownloadString(host);
string[] sections = BreakCSVLine(data);
if (sections.Length != freegeoipDataSectionsCount) throw new ArgumentException("Data returned from FreeGeoIP has changed format!");
addr = IPAddress.Parse(sections[freegeoipDataAddress]);
CountryCode = sections[freegeoipDataCountryCode];
Country = sections[freegeoipDataCountry];
RegionCode = sections[freegeoipDataRegionCode];
Region = sections[freegeoipDataRegion];
City = sections[freegeoipDataCity];
Zipcode = sections[freegeoipDataZipcode];
Metro = sections[freegeoipDataMetro];
Area = sections[freegeoipDataArea];
float lat = float.Parse(sections[freegeoipDataLatitude]);
float lon = float.Parse(sections[freegeoipDataLongditude]);
LatLong = new PointF(lon, lat);
}
}
catch (Exception)
{
addr = IPAddress.None;
}
Address = addr;
}
All it does is request the info from FreeGeoIP and process it into the various data areas.
private string[] BreakCSVLine(string rawCSV, char sep = ',')
{
List<string> data = new List<string>();
bool inString = false;
StringBuilder sb = new StringBuilder();
foreach (char c in rawCSV.Trim('\r', '\n'))
{
if (inString)
{
if (c == '"')
{
inString = false;
}
else
{
sb.Append(c);
}
}
else
{
if (c == sep)
{
data.Add(sb.ToString());
sb.Clear();
}
else if (c == '"')
{
inString = true;
}
else
{
sb.Append(c);
}
}
}
data.Add(sb.ToString());
return data.ToArray();
}
You'll find the whole class in the sample download.
Points of Interest
It's surprising which pool your IP can come from: I got London, Birmingham, and Llanelli in two days of checking.
It's also annoying how intermittent disconnection problems stop happening when you are waiting for your ISP to call you back about the problem...
History
2014-07-03 First version
2014-07-04 Typos :O loads of typos....the article submission wizard needs a spell checker... :laugh: