首先,要获取到一个IP地址,可参照上文:http://blog.csdn.net/konw_nothing/article/details/8888526
第一种方式:
读取纯真IP库的封装类:
要下载数据文件的话,直接百度搜“纯真ip数据库”,一般就能找到了。文件名通常是 qqwry.dat
using System;
using System.IO;
using System.Text;
///
/// IP对象类,该对象包含所属国家和地区
///
public class IPLocation
{
public string ISP { get; set; }
public string Area { get; set; }
}
///
/// 读取QQ纯真IP数据库
///
public class QQWry
{
//第一种模式
private const byte REDIRECT_MODE_1 = 0x01;
//第二种模式
private const byte REDIRECT_MODE_2 = 0x02;
//每条记录长度
private const int IP_RECORD_LENGTH = 7;
//数据库文件
private FileStream ipFile = null;
private const string unISP = "未知ISP";
private const string unArea = "未知地区";
//索引开始位置
private long ipBegin;
//索引结束位置
private long ipEnd;
//IP地址对象
private IPLocation loc;
//存储文本内容
private byte[] buf;
//存储3字节
private byte[] b3;
//存储4字节
private byte[] b4;
///
/// 构造函数
///
/// IP数据库文件绝对路径
///
public QQWry(string ipfile)
{
buf = new byte[100];
b3 = new byte[3];
b4 = new byte[4];
lock (this)
{
ipFile = new FileStream(ipfile, FileMode.Open);
ipBegin = ReadLong4(0);
ipEnd = ReadLong4(4);
loc = new IPLocation();
}
}
///
/// 搜索IP地址搜索
///
///
///
public IPLocation SearchIPLocation(string ip)
{
//将字符IP转换为字节
string[] ipSp = ip.Split('.');
if (ipSp.Length != 4)
{
ip = "127.0.0.1";
ipSp = ip.Split('.');
}
byte[] IP = new byte[4];
for (int i = 0; i < IP.Length; i++)
{
IP[i] = (byte)(Int32.Parse(ipSp[i]) & 0xFF);
}
IPLocation local = null;
long offset = LocateIP(IP);
if (offset != -1)
{
local = getIPLocation(offset);
}
if (local == null)
{
local = new IPLocation();
local.Area = unArea;
local.ISP = unISP;
}
return local;
}
///
/// 取得具体信息
///
///
///
private IPLocation getIPLocation(long offset)
{
ipFile.Position = offset + 4;
//读取第一个字节判断是否是标志字节
byte one = (byte)ipFile.ReadByte();
if (one == REDIRECT_MODE_1)
{
//第一种模式
//读取国家偏移
long countryOffset = ReadLong3();
//转至偏移处
ipFile.Position = countryOffset;
//再次检查标志字节
byte b = (byte)ipFile.ReadByte();
if (b == REDIRECT_MODE_2)
{
loc.Area = ReadString(ReadLong3());
ipFile.Position = countryOffset + 4;
}
else
loc.Area = ReadString(countryOffset);
//读取运营商标志
loc.ISP = ReadArea(ipFile.Position);
}
else if (one == REDIRECT_MODE_2)
{
//第二种模式
loc.Area = ReadString(ReadLong3());
loc.ISP = ReadArea(offset + 8);
}
else
{
//普通模式
loc.Area = ReadString(--ipFile.Position);
loc.ISP = ReadString(ipFile.Position);
}
ipFile.Close();
return loc;
}
///
/// 读取地区名称
///
///
///
private string ReadArea(long offset)
{
ipFile.Position = offset;
byte one = (byte)ipFile.ReadByte();
if (one == REDIRECT_MODE_1 || one == REDIRECT_MODE_2)
{
long areaOffset = ReadLong3(offset + 1);
return (areaOffset == 0) ? unArea : ReadString(areaOffset);
}
else
{
return ReadString(offset);
}
}
///
/// 读取字符串
///
///
///
private string ReadString(long offset)
{
ipFile.Position = offset;
int i = 0;
for (i = 0, buf[i] = (byte)ipFile.ReadByte(); buf[i] != (byte)(0); buf[++i] = (byte)ipFile.ReadByte()) ;
return (i > 0) ? Encoding.Default.GetString(buf, 0, i) : "";
}
///
/// 查找IP地址所在的绝对偏移量
///
///
///
private long LocateIP(byte[] ip)
{
long m = 0;
int r;
//比较第一个IP项
ReadIP(ipBegin, b4);
r = CompareIP(ip, b4);
if (r == 0)
return ipBegin;
else if (r < 0)
return -1;
//开始二分搜索
for (long i = ipBegin, j = ipEnd; i < j; )
{
m = this.GetMiddleOffset(i, j);
ReadIP(m, b4);
r = CompareIP(ip, b4);
if (r > 0)
i = m;
else if (r < 0)
{
if (m == j)
{
m = j -= IP_RECORD_LENGTH;
}
else
{
j = m;
}
}
else
return ReadLong3(m + 4);
}
m = ReadLong3(m + 4);
ReadIP(m, b4);
return (CompareIP(ip, b4) <= 0) ? m : -1;
}
///
/// 从当前位置读取四字节,此四字节是IP地址
///
///
///
private void ReadIP(long offset, byte[] ip)
{
ipFile.Position = offset;
ipFile.Read(ip, 0, ip.Length);
byte tmp = ip[0];
ip[0] = ip[3];
ip[3] = tmp;
tmp = ip[1];
ip[1] = ip[2];
ip[2] = tmp;
}
///
/// 比较IP地址是否相同
///
///
///
/// 0:相等,1:ip大于beginIP,-1:小于
private int CompareIP(byte[] ip, byte[] beginIP)
{
for (int i = 0; i < 4; i++)
{
int r = CompareByte(ip[i], beginIP[i]);
if (r != 0)
return r;
}
return 0;
}
///
/// 比较两个字节是否相等
///
///
///
///
private int CompareByte(byte bsrc, byte bdst)
{
if ((bsrc & 0xFF) > (bdst & 0xFF))
return 1;
else if ((bsrc ^ bdst) == 0)
return 0;
else
return -1;
}
///
/// 从当前位置读取4字节,转换为长整型
///
///
///
private long ReadLong4(long offset)
{
long ret = 0;
ipFile.Position = offset;
ret |= (ipFile.ReadByte() & 0xFF);
ret |= ((ipFile.ReadByte() << 8) & 0xFF00);
ret |= ((ipFile.ReadByte() << 16) & 0xFF0000);
ret |= ((ipFile.ReadByte() << 24) & 0xFF000000);
return ret;
}
///
/// 根据当前位置,读取3字节
///
///
///
private long ReadLong3(long offset)
{
long ret = 0;
ipFile.Position = offset;
ret |= (ipFile.ReadByte() & 0xFF);
ret |= ((ipFile.ReadByte() << 8) & 0xFF00);
ret |= ((ipFile.ReadByte() << 16) & 0xFF0000);
return ret;
}
///
/// 从当前位置读取3字节
///
///
private long ReadLong3()
{
long ret = 0;
ret |= (ipFile.ReadByte() & 0xFF);
ret |= ((ipFile.ReadByte() << 8) & 0xFF00);
ret |= ((ipFile.ReadByte() << 16) & 0xFF0000);
return ret;
}
///
/// 取得begin和end中间的偏移
///
///
///
///
private long GetMiddleOffset(long begin, long end)
{
long records = (end - begin) / IP_RECORD_LENGTH;
records >>= 1;
if (records == 0)
records = 1;
return begin + records * IP_RECORD_LENGTH;
}
}
IPLocation ip = new QQWry(Server.MapPath("~/App_Data/QQWry.Dat")).SearchIPLocation("58.83.255.255");
Response.Write("ISP:" + ip.ISP + "
");//铁通
Response.Write("Area:" + ip.Area);//北京市朝阳区
第二种方式:
使用第三方接口
介绍一种新浪的接口:其他接口大同小异
接口地址:http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip={ip}
public class IpDetail
{
public string Ret { get; set; }
public string Start { get; set; }
public string End { get; set; }
public string Country { get; set; }
public string Province { get; set; }
public string City { get; set; }
public string District { get; set; }
public string Isp { get; set; }
public string Type { get; set; }
public string Desc { get; set; }
public static IpDetail Get(string ipAddress, Encoding sourceEncoding)
{
string ip = string.Empty;
if (sourceEncoding == null)
sourceEncoding = Encoding.UTF8;
using (var receiveStream = System.Net.WebRequest.Create(string.Format("http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip={0}", ipAddress)).GetResponse().GetResponseStream())
{
using (var sr = new StreamReader(receiveStream, sourceEncoding))
{
ip = sr.ReadToEnd();
}
}
return !string.IsNullOrEmpty(ip) ? new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize(ip) : null;
}
}
IpDetail d = IpDetail.Get("58.83.255.255", null);
Response.Write(d.Country + "
");
Response.Write(d.Province + "
");
Response.Write(d.City + "
");
Response.Write(d.Isp);
另外,可以结合两种方式,当纯真库查不出数据时,有可能是纯真库没有及时更新,那么就能用接口方式来获取,一般第三方的IP库还是有保证的。