1. 準備工做git
準備好這兩個就能夠了。github
2. 敲代碼數據庫
我使用的操做系統是 CentOS7.1。bootstrap
2.1 編譯 libmaxminddb
把 libmaxminddb 的代碼下載下來,隨便放在什麼地方, 而後解壓,進入解壓後的目錄,執行 bootstrap,configure,make服務器
$ tar xzf libmaxminddb-1.3.1.tar.gz $ cd libmaxminddb-1.3.1 $ ./bootstrap $ ./configure $ make
1.在執行 bootstrap 的時候可能會報錯,應該是缺乏 autoconf 之類的自動構建工具致使的,到谷歌或者百度查詢一下安裝便可。ide
2.在執行 make 命令的時候,也會報錯,不過報錯信息指向的是 libmaxminddb-1.3.1/t 裏面缺乏 libtap/tap.h。 https://github.com/pozorvlak/libtap 是 libtap 在 GitHub 上的地址, 其項目首頁上的註釋是:Testing library for C, implementing the Test Anything Protocol. Written by Nik Clayton.工具
既然是測試使用的,那麼不編譯應該也沒什麼大問題。測試
3.看 make 命令後的編譯記錄,能夠發現 libmaxminddb.a 靜態連接庫已經編譯好了, 而且放在了 libmaxminddb-1.3.1/src/.libs 目錄裏面。ui
[root@fengbo libmaxminddb-1.3.1]# ls src/.libs/ -l total 312
-rw-r--r--. 1 root root 12632 Dec 8 22:30 data-pool.o -rw-r--r--. 1 root root 111620 Dec 8 22:30 libmaxminddb.a lrwxrwxrwx. 1 root root 18 Dec 8 22:30 libmaxminddb.la -> ../libmaxminddb.la -rw-r--r--. 1 root root 959 Dec 8 22:30 libmaxminddb.lai lrwxrwxrwx. 1 root root 21 Dec 8 22:30 libmaxminddb.so -> libmaxminddb.so.0.0.7 lrwxrwxrwx. 1 root root 21 Dec 8 22:30 libmaxminddb.so.0 -> libmaxminddb.so.0.0.7
-rwxr-xr-x. 1 root root 79477 Dec 8 22:30 libmaxminddb.so.0.0.7
-rw-r--r--. 1 root root 100104 Dec 8 22:30 maxminddb.o
2.2 編寫示例代碼this
示例代碼是從 maxmind 的官方 GitHub 上直接複製下來的。不過我加了幾條日誌信息。 https://github.com/maxmind/libmaxminddb/blob/master/doc/libmaxminddb.md#example
代碼以下:$cat example.c
#include <errno.h> #include "maxminddb.h" #include <stdlib.h> #include <string.h> #define xdebug(fmt, arg...) \ do{\ printf("%s %d : ", __FILE__, __LINE__); \ printf(fmt, ##arg); \ printf("\n"); \ }while(0) int main(int argc, char **argv) { if(argc < 2) { xdebug("Usage : %s dbfilename IP", argv[0]); } char *filename = argv[1]; char *ip_address = argv[2]; MMDB_s mmdb; int status = MMDB_open(filename, MMDB_MODE_MMAP, &mmdb); if (MMDB_SUCCESS != status) { fprintf(stderr, "\n Can't open %s - %s\n", filename, MMDB_strerror(status)); if (MMDB_IO_ERROR == status) { fprintf(stderr, " IO error: %s\n", strerror(errno)); } exit(1); } int gai_error, mmdb_error; MMDB_lookup_result_s result = MMDB_lookup_string(&mmdb, ip_address, &gai_error, &mmdb_error); if (0 != gai_error) { fprintf(stderr, "\n Error from getaddrinfo for %s - %s\n\n", ip_address, gai_strerror(gai_error)); exit(2); } if (MMDB_SUCCESS != mmdb_error) { fprintf(stderr, "\n Got an error from libmaxminddb: %s\n\n", MMDB_strerror(mmdb_error)); exit(3); } MMDB_entry_data_list_s *entry_data_list = NULL; int exit_code = 0; if (result.found_entry) { int status = MMDB_get_entry_data_list(&result.entry, &entry_data_list); if (MMDB_SUCCESS != status) { fprintf( stderr, "Got an error looking up the entry data - %s\n", MMDB_strerror(status)); exit_code = 4; goto end; } if (NULL != entry_data_list) { MMDB_dump_entry_data_list(stdout, entry_data_list, 2); } } else { fprintf( stderr, "\n No entry for this IP address (%s) was found\n\n", ip_address); exit_code = 5; } end: MMDB_free_entry_data_list(entry_data_list); MMDB_close(&mmdb); exit(exit_code); }
編譯咱們的示例代碼:
把 libmaxminddb 源碼中的 libmaxminddb-1.3.1/include/maxminddb_config.h 和 libmaxminddb-1.3.1/include/maxminddb.h 放到 example.c 所在的目錄下。 還有 libmaxminddb-1.3.1/src/.libs/libmaxminddb.a 也要放進來。
$ gcc -o example example.c ./libmaxminddb.a $ ls example example.c libmaxminddb.a maxminddb_config.h maxminddb.h
2.3 下載 GeoLite2 開源數據庫
到網頁 https://dev.maxmind.com/geoip/geoip2/geolite2/ 中,下載 GeoLite2 的數據庫。
Downloads
Database | MaxMind DB binary, gzipped | CSV format, zipped |
---|---|---|
GeoLite2 City | Download (md5 checksum) | Download (md5 checksum) |
GeoLite2 Country | Download (md5 checksum) | Download (md5 checksum) |
GeoLite2 ASN (Autonomous System Number) | Download (md5 checksum) | Download (md5 checksum) |
我下載的是 GeoLite2 City
數據庫。解壓後的文件以下:
[root@fengbo maxmind]# ls GeoLite2-City_20171205/ COPYRIGHT.txt GeoLite2-City.mmdb LICENSE.txt README.txt
2.4 測試一下這個程序的效果
先拿到一個 IP,好比 www.fengbohello.top 的 IP。
[root@fengbo maxmind]$ ping www.fengbohello.top PING www.fengbohello.top (139.199.212.133) 56(84) bytes of data. 64 bytes from 139.199.212.133: icmp_seq=1 ttl=48 time=41.7 ms
運行一下 example 試試看:
[root@fengbo maxmind]$ ./example GeoLite2-City_20171205/GeoLite2-City.mmdb "139.199.212.133" { "city": { "geoname_id": 1816670 <uint32>
"names": { "de": "Peking" <utf8_string>
"en": "Beijing" <utf8_string>
"es": "Pekín" <utf8_string>
"fr": "Pékin" <utf8_string>
"ja": "北京市" <utf8_string>
"pt-BR": "Pequim" <utf8_string>
"ru": "Пекин" <utf8_string>
"zh-CN": "北京" <utf8_string> } } "continent": { "code": "AS" <utf8_string>
"geoname_id": 6255147 <uint32>
"names": { "de": "Asien" <utf8_string>
"en": "Asia" <utf8_string>
"es": "Asia" <utf8_string>
"fr": "Asie" <utf8_string>
"ja": "アジア" <utf8_string>
"pt-BR": "Ásia" <utf8_string>
"ru": "Азия" <utf8_string>
"zh-CN": "亞洲" <utf8_string> } } "country": { "geoname_id": 1814991 <uint32>
"iso_code": "CN" <utf8_string>
"names": { "de": "China" <utf8_string>
"en": "China" <utf8_string>
"es": "China" <utf8_string>
"fr": "Chine" <utf8_string>
"ja": "中國" <utf8_string>
"pt-BR": "China" <utf8_string>
"ru": "Китай" <utf8_string>
"zh-CN": "中國" <utf8_string> } } "location": { "accuracy_radius": 50 <uint16>
"latitude": 39.928900 <double>
"longitude": 116.388300 <double>
"time_zone": "Asia/Shanghai" <utf8_string> } "registered_country": { "geoname_id": 1814991 <uint32>
"iso_code": "CN" <utf8_string>
"names": { "de": "China" <utf8_string>
"en": "China" <utf8_string>
"es": "China" <utf8_string>
"fr": "Chine" <utf8_string>
"ja": "中國" <utf8_string>
"pt-BR": "China" <utf8_string>
"ru": "Китай" <utf8_string>
"zh-CN": "中國" <utf8_string> } } "subdivisions": [ { "geoname_id": 2038349 <uint32>
"iso_code": "11" <utf8_string>
"names": { "en": "Beijing" <utf8_string>
"fr": "Municipalité de Pékin" <utf8_string>
"zh-CN": "北京市" <utf8_string> } } ] }
我擦,解析結果竟然是北京。我問了十三哥,他說咱們的服務器是騰訊雲的,當時選擇的是深圳機房。
下面是使用不一樣的廠商獲得的結果:
廠商 | 地理位置 |
---|---|
百度 | 廣東省廣州市 騰訊集團 |
ip.cn | 廣東省深圳市 騰訊雲 |
freegeoip.net | China.Beijing |
新浪:int.dpool.sina.com.cn | 中國.廣東.廣州 |
淘寶:ip.taobao.com | 中國.華南.廣東省.廣州市.電信 |
騰訊:ip.qq.com | 中國廣東省廣州市 未知 |
有意思吧,我也不知道該信誰的。
同步發表:https://www.fengbohello.top/archives/ip2location-geolite2