///<summary>
/// 提供从纯真IP数据库搜索IP信息的方法;
///</summary>
public class IPSelect
{
FileStream ipFile;
long ip;
public string ipfilePath;
///<summary>
/// 构造函数
///</summary>
///<param name="ipfilePath">纯真IP数据库路径</param>
public IPSelect()
{
ipfilePath = "纯真IP数据库路径";//TextUtility.GetFullPath( Utility.GetIPDbFilePath );
} ///<summary>
/// 地理位置,包括国家和地区
///</summary>
public struct IPLocation
{
public string country, area;
} ///<summary>
/// 获取指定IP所在地理位置实体
///</summary>
///<param name="strIP">要查询的IP地址</param>
///<returns></returns>
public string GetIPLocation( string strIP )
{
if (!File.Exists(ipfilePath))
{
return "";
}
ip = IPToLong( strIP ); //将字符串形式的IP转换位long
IPLocation loc = new IPLocation();
try
{
ipFile = new FileStream(ipfilePath, FileMode.Open, FileAccess.Read); //文件流
long[] ipArray = BlockToArray(ReadIPBlock()); //
long offset = SearchIP(ipArray, , ipArray.Length - ) * + ;
ipFile.Position += offset; //跳过起始IP
ipFile.Position = ReadLongX() + ; //跳过结束IP int flag = ipFile.ReadByte(); //读取标志
if (flag == ) //表示国家和地区被转向
{
ipFile.Position = ReadLongX();
flag = ipFile.ReadByte(); //再读标志
}
long countryOffset = ipFile.Position;
loc.country = ReadString(flag); if (flag == )
{
ipFile.Position = countryOffset + ;
}
flag = ipFile.ReadByte();
loc.area = ReadString(flag); ipFile.Close();
ipFile = null;
}
catch
{
return "";
}
return loc.country + loc.area;
}
///<summary>
/// 将字符串形式的IP转换位long
///</summary>
///<param name="strIP"></param>
///<returns></returns>
public long IPToLong( string strIP )
{
byte[] ip_bytes = new byte[];
string[] strArr = strIP.Split( new char[] { '.' } );
for( int i = ; i < ; i++ )
{
ip_bytes[i] = byte.Parse( strArr[ - i] );
}
return BitConverter.ToInt64( ip_bytes, );
}
///<summary>
/// 将索引区字节块中的起始IP转换成Long数组
///</summary>
///<param name="ipBlock"></param>
long[] BlockToArray( byte[] ipBlock )
{
long[] ipArray = new long[ipBlock.Length / ];
int ipIndex = ;
byte[] temp = new byte[];
for( int i = ; i < ipBlock.Length; i += )
{
Array.Copy( ipBlock, i, temp, , );
ipArray[ipIndex] = BitConverter.ToInt64( temp, );
ipIndex++;
}
return ipArray;
}
///<summary>
/// 从IP数组中搜索指定IP并返回其索引
///</summary>
///<param name="ipArray">IP数组</param>
///<param name="start">指定搜索的起始位置</param>
///<param name="end">指定搜索的结束位置</param>
///<returns></returns>
int SearchIP( long[] ipArray, int start, int end )
{
int middle = ( start + end ) / ;
if( middle == start )
return middle;
else if( ip < ipArray[middle] )
return SearchIP( ipArray, start, middle );
else
return SearchIP( ipArray, middle, end );
}
///<summary>
/// 读取IP文件中索引区块
///</summary>
///<returns></returns>
byte[] ReadIPBlock()
{
long startPosition = ReadLongX( );
long endPosition = ReadLongX( );
long count = ( endPosition - startPosition ) / + ;//总记录数
ipFile.Position = startPosition;
byte[] ipBlock = new byte[count * ];
ipFile.Read( ipBlock, , ipBlock.Length );
ipFile.Position = startPosition;
return ipBlock;
}
///<summary>
/// 从IP文件中读取指定字节并转换位long
///</summary>
///<param name="bytesCount">需要转换的字节数,主意不要超过8字节</param>
///<returns></returns>
long ReadLongX( int bytesCount )
{
byte[] _bytes = new byte[];
ipFile.Read( _bytes, , bytesCount );
return BitConverter.ToInt64( _bytes, );
}
///<summary>
/// 从IP文件中读取字符串
///</summary>
///<param name="flag">转向标志</param>
///<returns></returns>
string ReadString( int flag )
{
if( flag == || flag == )//转向标志
ipFile.Position = ReadLongX( );
else
ipFile.Position -= ; List<byte> list = new List<byte>();
byte b = (byte)ipFile.ReadByte();
while( b > )
{
list.Add( b );
b = (byte)ipFile.ReadByte();
}
return Encoding.Default.GetString( list.ToArray() );
}
}
        /// <summary>
/// 根据IP的地理位置
/// </summary>
/// <param name="IP">IP</param>
/// <returns>地理位置</returns>
protected string GetAddressWithIP(string IP)
{
IPSelect IPSelect = new IPSelect();
if (string.IsNullOrEmpty(IP))
{
IP = "127.0.0.1";
}
return IPSelect.GetIPLocation(IP);
}

纯真IP数据库格式文档在【IP数据库文件

根据IP地址获得地理位置的更多相关文章

  1. python36异步任务 获取ip地址的地理位置

    # encoding: utf-8 import asyncio import requests import functools url = "http://ip.zxinc.org/ap ...

  2. Linux下Python获取IP地址

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

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

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

  4. MFC C++ 获取外网IP地址

    #include <afxinet.h> //GB2312 转换成 Unicode wchar_t* GB2312ToUnicode(const char* szGBString) { U ...

  5. 腾讯新浪通过IP地址获取当前地理位置(省份)的接口

    腾讯新浪通过IP地址获取当前地理位置(省份)的接口  腾讯的接口是 ,返回数组 http://fw.qq.com/ipaddress 返回值 var IPData = new Array(" ...

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

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

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

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

  8. linux c++ curl 根据IP地址获得当前网络的所在的地理位置

    注意: 可能每个电脑的默认中文编码格式不同,有时会出现乱码,需要对返回内容进行编码转换,或者换成可指定编码格式的接口.如  搜狐IP地址查询接口(可设置编码):http://pv.sohu.com/c ...

  9. 通过IP地址定位准确的地理位置

    事情的经过时这样的: 朋友发来一封QQ邮件原文,询问里面显示的IP地址是不是真是的IP地址.然后,我就解锁了一项新技能:通过IP地址定位准确的地理位置 在这里收藏一下这个网址:http://www.8 ...

随机推荐

  1. ThinkPHP第十天(_initialize方法,SESSION销毁,分组配置,include文件引入,JOIN用法)

    1.Action类中的_initialize()函数,先于任何自定义操作函数运行,可认为是控制器的前置操作.可用于检测用户是否登录等检测. 如果多个模块(Action)需要相同_initialize( ...

  2. Python之路:迭代器和yield生成器

    一.迭代器 对于Python 列表的 for 循环,他的内部原理:查看下一个元素是否存在,如果存在,则取出,如果不存在,则报异常 StopIteration.(python内部对异常已处理) 使用迭代 ...

  3. Week14(12月11日):路由

    Part I:提问 =========================== 1.Visual Studio 2013自带ASP.NET MVC最高版本为(). A.3  B.4  C.5  D.6 2 ...

  4. java 抽象类与接口的区别 整理

    抽象类与接口的区别 抽象类 包含抽象方法的类就是抽象类,声明的语句:abstract class 必须是public protected 接口 对行为的抽象,声明语句:interface 抽象方法的修 ...

  5. js 时间戳转为日期格式

    原文:js 时间戳转为日期格式 js 时间戳转为日期格式 什么是Unix时间戳(Unix timestamp): Unix时间戳(Unix timestamp),或称Unix时间(Unix time) ...

  6. js php xmlrequest 上传图片

    本来想用插件上传图片的,后来自己写了一个简单的js实现异步的图片上传,不多说上代码很easy upload.php <?php if(isset($_FILES["myfile&quo ...

  7. TCP/IP之坚持定时器、报活定时器

    TCP中的四个定时器: 1.超时定时器(最复杂的一个) 2.坚持定时器 3.保活定时器 4.2MSL定时器 坚持定时器用于防止通告窗口为0以后c/s双方相互等待死锁的情况:而保活定时器则用于处理半开发 ...

  8. 将树莓派变成一个web服务器(2):Nginx+Flask+uWSGI部署全过程

    1)安装Flask,uwsgi,nginx sudo apt-get update sudo apt-get install python-flask #Flask sudo apt-get inst ...

  9. ZOJ 3331 Process the Tasks 双塔Dp

    用dp[i][j]表示当前安排好了前i个任务,且机器A和机器B完成当前分配到的所有任务的时间差为j(这里j可正可负,实现的时候需要加个offset)时,完成这些任务的最早时间.然后根据j的正负,分别考 ...

  10. 【转】介绍几个图论和复杂网络的程序库 —— BGL,QuickGraph,igraph和NetworkX

    原文来自:http://blog.sciencenet.cn/blog-404069-297233.html 作复杂网络研究离不开对各种实际或模拟网络的统计.计算.绘图等工作.对于一般性的工作,我们可 ...