1. 准备工作

准备好这两个就可以了。


2. 敲代码

我使用的操作系统是 CentOS7.1。

2.1 编译 libmaxminddb
把 libmaxminddb 的代码下载下来,随便放在什么地方, 然后解压,进入解压后的目录,执行 bootstrap,configure,make

$ tar xzf libmaxminddb-1.3..tar.gz
$ cd libmaxminddb-1.3.
$ ./bootstrap
$ ./configure
$ make

1.在执行 bootstrap 的时候可能会报错,应该是缺少 autoconf 之类的自动构建工具导致的,到谷歌或者百度查询一下安装即可。

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 目录里面。

[root@fengbo libmaxminddb-1.3.]# ls src/.libs/ -l
total
-rw-r--r--. root root Dec : data-pool.o
-rw-r--r--. root root Dec : libmaxminddb.a
lrwxrwxrwx. root root Dec : libmaxminddb.la -> ../libmaxminddb.la
-rw-r--r--. root root Dec : libmaxminddb.lai
lrwxrwxrwx. root root Dec : libmaxminddb.so -> libmaxminddb.so.0.0.
lrwxrwxrwx. root root Dec : libmaxminddb.so. -> libmaxminddb.so.0.0.
-rwxr-xr-x. root root Dec : libmaxminddb.so.0.0.
-rw-r--r--. root root Dec : maxminddb.o

2.2 编写示例代码

示例代码是从 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() int main(int argc, char **argv)
{
if(argc < ) {
xdebug("Usage : %s dbfilename IP", argv[]);
}
char *filename = argv[];
char *ip_address = argv[]; 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();
} int gai_error, mmdb_error;
MMDB_lookup_result_s result =
MMDB_lookup_string(&mmdb, ip_address, &gai_error, &mmdb_error); if ( != gai_error) {
fprintf(stderr,
"\n Error from getaddrinfo for %s - %s\n\n",
ip_address, gai_strerror(gai_error));
exit();
} if (MMDB_SUCCESS != mmdb_error) {
fprintf(stderr,
"\n Got an error from libmaxminddb: %s\n\n",
MMDB_strerror(mmdb_error));
exit();
} MMDB_entry_data_list_s *entry_data_list = NULL; int exit_code = ;
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 = ;
goto end;
} if (NULL != entry_data_list) {
MMDB_dump_entry_data_list(stdout, entry_data_list, );
}
} else {
fprintf(
stderr,
"\n No entry for this IP address (%s) was found\n\n",
ip_address);
exit_code = ;
} 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) () bytes of data.
bytes from 139.199.212.133: icmp_seq= ttl= time=41.7 ms

运行一下 example 试试看:

[root@fengbo maxmind]$ ./example GeoLite2-City_20171205/GeoLite2-City.mmdb "139.199.212.133"
{
"city":
{
"geoname_id":
<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":
<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":
<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":
<uint16>
"latitude":
39.928900 <double>
"longitude":
116.388300 <double>
"time_zone":
"Asia/Shanghai" <utf8_string>
}
"registered_country":
{
"geoname_id":
<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":
<uint32>
"iso_code":
"" <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

使用 GeoIP2 获取 IP 的地理位置的更多相关文章

  1. 根据ip地址从第三方接口获取详细的地理位置

    最近项目某个功能需要根据ip地址从第三方接口获取详细的地理位置,从网上找了很多例子,主要接口有新浪的,淘宝的,腾讯的.试了淘宝的,如果是数量级小的还可以,如果数量级达到上十万级就速度慢了,会导致系统崩 ...

  2. PHP获取操作系统、IP、地理位置、浏览器、ISP等信息_PHP类代码

    PHP语言.浏览器.操作系统.IP.地理位置.ISP,本PHP类里面有以下几种方法,同时也是用法说明: <?php class class_guest_info{ function GetLan ...

  3. php获取ip地址所在的地理位置的实现

    1,通过腾讯或者新浪提供的接口来获取(新浪和腾讯类似) <?php     function getIPLocation($queryIP){      $url = 'http://ip.qq ...

  4. 使用纯真IP库获取用户端地理位置信息

    引言 在一些电商类或者引流类的网站中经常会有获取用户地理位置信息的需求,下面我分享一个用纯真IP库获取用户地理位置信息的方案. 正文 第一步:本文的方案是基于纯真IP库的,所以首先要去下载最新的纯真I ...

  5. [日志分析]Graylog2进阶之获取Nginx来源IP的地理位置信息

    如果你们觉得graylog只是负责日志收集的一个管理工具,那就too young too naive .日志收集只是graylog的最最基础的用法,graylog有很多实用的数据清洗和处理的进阶用法. ...

  6. 使用navigator.geolocation来获取用户的地理位置信息

    使用navigator.geolocation来获取用户的地理位置信息 W3C 中新添加了一个名为 Geolocation的 API 规范,Geoloaction API的作用就是通过浏览器获取用户的 ...

  7. Linux下Python获取IP地址

    <lnmp一键安装包>中需要获取ip地址,有2种情况:如果服务器只有私网地址没有公网地址,这个时候获取的IP(即私网地址)不能用来判断服务器的位置,于是取其网关地址用来判断服务器在国内还是 ...

  8. PHP语言、浏览器、操作系统、IP、地理位置、ISP

    )]; } else { $Isp = 'None'; } return $Isp; }}

  9. PHP 获取IP地址位置信息「聚合数据API」

    聚合数据 提供了[查询IP所属区域]的服务接口,只需要以 GET 请求的方式向 API 传入 IP地址 和 APPKEY 即可获得查询结果. 这里的难点主要在于如何通过PHP获取客户端IP地址,以及如 ...

随机推荐

  1. 【基础】链表的储存结构说明(python)

    [实现链表的添加] class aNode(): def __init__(self,data=None,nxt=None): self.data=data self.nxt=nxt class ru ...

  2. python中sqlite问题和坑

    import sqlite3 #导入模块 conn = sqlite3.connect('example.db') C=conn.cursor() #创建表 C.execute('''CREATE T ...

  3. shell编程第四天

  4. Python datetime与timestamp之间的转换

    # !!!! Python 2 datetime.datetime 对象没有timestamp方法! 在用Python处理datetime和timestamp的转换时发现在时区方面,Python的处理 ...

  5. pip安装django失败

    pip install django时提示 Cannot fetch index base URL https://mirrors.tuna.tsinghua.edu.cn/pypi/simple/, ...

  6. 【三边定位】 演示程序V0.1

    忙于工作,这个小东西一直没有空去弄, 最近简单修改了些算法, 精度还有待提高. 贴一张图片 坐上角的坐标是鼠标点(31,17),后面location 是三边定位算出来的(31,19),后面跟的erro ...

  7. js form表单 鼠标移入弹出提示功能

    JS 部分 /* Copyright (C) 2009 - 2012 Email: wangking717@qq.com WebSite: Http://wangking717.javaeye.com ...

  8. Sublime Text3 最新版本V3.1.1 build3117注册码,亲测可以完美激活~

    Sublime Text 3 最新注册码 官网下载的最新版本V3.1.1 build3117,亲测以下注册码可以正常激活 ----- BEGIN LICENSE ----- sgbteam Singl ...

  9. 使用Three.js为QQ用户生成3D头像阵列

    东西其实比较简单,就是输出某一范围内QQ账号的3D头像 涉及的技术主要是Three.js的基本使用 而后通过腾讯的接口异步并发请求QQ用户头像,Canavs作图生成Texture应用在球体上 需要注意 ...

  10. 区间dp板子题:[noi1995]石子合并

    非常经典的区间dp模板 对于每一个大于二的区间 我们显然都可以将它拆分成两个子序列 那么分别计算对于每个取最优值即可 #pragma GCC optimize("O2") #inc ...