3

I'm looking to geolocate my server requests by continent.

Basically, after doing some initial research, it seems that there are 3 approaches: 1) using the geolocation provided by browsers (but I think noone seriously click "Yes" when the browser is asking permission to use geolocation); 2) getting a list of IP addresses, putting that list in a database on your server and then every time a request comes in, read from this DB; I'd hate to have have to hit the DB at every request. 3) make an HTTP call to an external server to get the location; that could even be slower than 2).

Basically, I don't really care to know exactly where the users are, I just need to know which continent they're on: North Armerica, Europe...

Is there a way to do this that doesn't require any user interaction and doesn't require reading a DB on every request? When I go to www.intel.com I get automatically rerouted to the French site; how do they do that?

Thanks for your suggestions.

Aristos
  • 66,005
  • 16
  • 114
  • 150
frenchie
  • 51,731
  • 109
  • 304
  • 510
  • You could try checking the Accept-Language header, but you would still want a fallback, and i think some geodatabase is still your best guess in that case – sroes Nov 19 '12 at 20:43

3 Answers3

7

There are some free and some commercial database that can tell you from the ip, where is coming from.

The free database from maxmind [*]: http://dev.maxmind.com/geoip/geolite

and two commercial:
http://www.ip2location.com
http://www.maxmind.com

In this site you can also find asp.net examples on how you can use that data, but also they have other free services that you can use and see where the use is come from.

Get api samples together with the database from: http://www.maxmind.com/download/geoip/

If only the country is what you need for then this database file

http://www.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip

contains only the country, and is small compared with the rest.

How this works in few words: The database is in format of:

"1.20.0.0","1.20.255.255","18087936","18153471","TH","Thailand"
"1.21.0.0","1.21.255.255","18153472","18219007","JP","Japan"
"1.22.0.0","1.23.255.255","18219008","18350079","IN","India"
"1.24.0.0","1.31.255.255","18350080","18874367","CN","China" 

the long numbers are the translation of the ip. So you read the IP of your user and then with a function you convert it to long and then you search the database, where is this long number fits.

public long addrToNum(IPAddress Address)
{
    byte[] b = BitConverter.GetBytes(Address.Address);

    if (b.Length == 8)
        return (long)(((long)16777216 * b[0]) + ((long)(65536 * b[1])) + ((long)(256 * b[2])) + b[3]);
    else
        return 0;
}

So if you add them in database then you index the database on this long numbers and look where the ip is in as:

Select TOP 1 * from GeoIPCountryWhois WITH (NOLOCK) Where @myIpToLong BETWEEN begin_num AND end_num

Its good to cache the result on a session variable and not search again and again on every page request.

[*] A big thanks to maxmind that still release the free database together with the commercial.

Aristos
  • 66,005
  • 16
  • 114
  • 150
  • Which one do I need: GeoLite Country IPv6 or GeoLite Country? – frenchie Nov 19 '12 at 20:52
  • @frenchie GeoLite Country - the IPv6 is is use the v6 ip's - I do not know if IP v6 return all, but the old ip is work on all. – Aristos Nov 19 '12 at 20:53
  • Is scanning a DB with 1 million rows an issue in terms of performance? – frenchie Nov 19 '12 at 21:00
  • @frenchie If you use the large database, then you need to add it to MS Sql, or MySql, there you index the ips start/end, then the search is very fast, but is not bad to cache the result on session and not scan the location on every call, but only on the first. If you use the Country database, then is even faster because is smaller. There is on the directory a country example on c# that you can use very easy. I use it, I have added to MS SQL. – Aristos Nov 19 '12 at 21:02
  • Yes, I plan to it in Sql server. Thanks for the answer; I think I'll go with a DB call. – frenchie Nov 19 '12 at 21:03
0

I've used this to geolocate IP addresses before when they requested access to my firewall. Not sure if this is what you're looking for, but it may help.

http://www.geobytes.com/iplocator.htm

BugBytes
  • 21
  • 3
0

It seems that you'd prefer second variant, but you don't need to hit the DB on every request - just cache the result in cookie, for example.

And a little bit of insanity - just to make you think about cost of extra DB request: you can convert some geo-DB (look for Aristos' answer) for your needs. Every IP can be converted to Int64 and you can make continent ranges, while converting DB to your format. For example, 0-10000 would be North America, 10000-20000 - Europe, 20000-30000 - North America again and so on, and the only task after such converting is to spot the IP in these ranges.

But you'll have to make a huge work to perform such converting and don't forget that it would be really big butthurt headache to renew it: IP-base isn't constant.
So, DB request + caching, probably, is the best option.

Smileek
  • 2,702
  • 23
  • 26