当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > asp.net DZ论坛中根据IP地址取得所在地的代码

ASP.NET
用 Asp.Net 建立一个在线 RSS 新闻聚合器的方法
关于前台调用后台事件__doPostBack函数
Bin 和 App_Code 文件夹介绍
.NET 2.0 的压缩功能代码
解决Visual Studio 2005 无法显示设计视图的方法
asp.net(c#)两种随机数的算法,可用抽考题
asp.net下url传递中文的解决方案
XmlReader 读取器读取内存流 MemoryStream 的注意事项
asp.net下创建、查询、修改带名称空间的 XML 文件的例子
使用.NET存储XML数据的方法
XslTransform.Transform将结果输出到字符串里的方法
安装 VS2005 SP1 有关问题的解决办法
asp.net下中文验证码,免费开源代码
自定义应用程序配置文件(app.config)
asp.net下使用DIME协议上传文件
动态改变ASP.net页面标题和动态指定页面样式表的方法
WEB上调用HttpWebRequest奇怪问题的解决方法
HTTP协议下用Web Service上传大文件的解决方案
asp.net下Response.ContentType类型汇总
ASP.NET User Control使用技巧一则

ASP.NET 中的 asp.net DZ论坛中根据IP地址取得所在地的代码


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-13   浏览: 130 ::
收藏到网摘: n/a

从dz .net版发现的这个不错的函数,大家以后就可以方便调用了 使用方法: IpSearch.GetAddressWithIP("202.96.128.167")
CS类代码
复制代码 代码如下:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
//引入的命名空间
using System.IO;
/// <summary>
/// 判断IP归属地类
/// </summary>
public class IpSearch
{
private static object lockHelper = new object();
static PHCZIP pcz = new PHCZIP();
static string filePath = "";
static bool fileIsExsit = true;
static IpSearch()
{
filePath = HttpContext.Current.Server.MapPath("~/ipdata.config");
pcz.SetDbFilePath(filePath);
}
/// <summary>
/// 返回IP查找结果
/// </summary>
/// <param name="IPValue">要查找的IP地址</param>
/// <returns></returns>
public static string GetAddressWithIP(string IPValue)
{
lock (lockHelper)
{
string result = pcz.GetAddressWithIP(IPValue.Trim());
if (fileIsExsit)
{
if (result.IndexOf("IANA") >= 0)
{
return "";
}
else
{
return result;
}
}
else
{
return null;
}
}
}
/// <summary>
/// 辅助类,用于保存IP索引信息
/// </summary>
///
public class CZ_INDEX_INFO
{
public UInt32 IpSet;
public UInt32 IpEnd;
public UInt32 Offset;
public CZ_INDEX_INFO()
{
IpSet = 0;
IpEnd = 0;
Offset = 0;
}
}
//读取纯真IP数据库类
public class PHCZIP
{
protected bool bFilePathInitialized;
protected string FilePath;
protected FileStream FileStrm;
protected UInt32 Index_Set;
protected UInt32 Index_End;
protected UInt32 Index_Count;
protected UInt32 Search_Index_Set;
protected UInt32 Search_Index_End;
protected CZ_INDEX_INFO Search_Set;
protected CZ_INDEX_INFO Search_Mid;
protected CZ_INDEX_INFO Search_End;
public PHCZIP()
{
bFilePathInitialized = false;
}
public PHCZIP(string dbFilePath)
{
bFilePathInitialized = false;
SetDbFilePath(dbFilePath);
}
//使用二分法查找索引区,初始化查找区间
public void Initialize()
{
Search_Index_Set = 0;
Search_Index_End = Index_Count - 1;
}
//关闭文件
public void Dispose()
{
if (bFilePathInitialized)
{
bFilePathInitialized = false;
FileStrm.Close();
//FileStrm.Dispose();
}
}

public bool SetDbFilePath(string dbFilePath)
{
if (dbFilePath == "")
{
return false;
}
try
{
FileStrm = new FileStream(dbFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
}
catch
{
return false;
}
//检查文件长度
if (FileStrm.Length < 8)
{
FileStrm.Close();
//FileStrm.Dispose();
return false;
}
//得到第一条索引的绝对偏移和最后一条索引的绝对偏移
FileStrm.Seek(0, SeekOrigin.Begin);
Index_Set = GetUInt32();
Index_End = GetUInt32();
//得到总索引条数
Index_Count = (Index_End - Index_Set) / 7 + 1;
bFilePathInitialized = true;
return true;
}
public string GetAddressWithIP(string IPValue)
{
if (!bFilePathInitialized)
{
return "";
}
Initialize();
UInt32 ip = IPToUInt32(IPValue);
while (true)
{
//首先初始化本轮查找的区间
//区间头
Search_Set = IndexInfoAtPos(Search_Index_Set);
//区间尾
Search_End = IndexInfoAtPos(Search_Index_End);
//判断IP是否在区间头内
if (ip >= Search_Set.IpSet && ip <= Search_Set.IpEnd)
return ReadAddressInfoAtOffset(Search_Set.Offset);

//判断IP是否在区间尾内
if (ip >= Search_End.IpSet && ip <= Search_End.IpEnd)
return ReadAddressInfoAtOffset(Search_End.Offset);
//计算出区间中点
Search_Mid = IndexInfoAtPos((Search_Index_End + Search_Index_Set) / 2);
//判断IP是否在中点
if (ip >= Search_Mid.IpSet && ip <= Search_Mid.IpEnd)
return ReadAddressInfoAtOffset(Search_Mid.Offset);
//本轮没有找到,准备下一轮
if (ip < Search_Mid.IpSet)
//IP比区间中点要小,将区间尾设为现在的中点,将区间缩小1倍。
Search_Index_End = (Search_Index_End + Search_Index_Set) / 2;
else
//IP比区间中点要大,将区间头设为现在的中点,将区间缩小1倍。
Search_Index_Set = (Search_Index_End + Search_Index_Set) / 2;
}
//return "";
}
private string ReadAddressInfoAtOffset(UInt32 Offset)
{
string country = "";
string area = "";
UInt32 country_Offset = 0;
byte Tag = 0;
//跳过4字节,因这4个字节是该索引的IP区间上限。
FileStrm.Seek(Offset + 4, SeekOrigin.Begin);
//读取一个字节,得到描述国家信息的“寻址方式”
Tag = GetTag();
if (Tag == 0x01)
{
//模式0x01,表示接下来的3个字节是表示偏移位置
FileStrm.Seek(GetOffset(), SeekOrigin.Begin);
//继续检查“寻址方式”
Tag = GetTag();
if (Tag == 0x02)
{
//模式0x02,表示接下来的3个字节代表国家信息的偏移位置
//先将这个偏移位置保存起来,因为我们要读取它后面的地区信息。
country_Offset = GetOffset();
//读取地区信息(注:按照Luma的说明,好像没有这么多种可能性,但在测试过程中好像有些情况没有考虑到,
//所以写了个ReadArea()来读取。
area = ReadArea();
//读取国家信息
FileStrm.Seek(country_Offset, SeekOrigin.Begin);
country = ReadString();
}
else
{
//这种模式说明接下来就是保存的国家和地区信息了,以'\0'代表结束。
FileStrm.Seek(-1, SeekOrigin.Current);
country = ReadString();
area = ReadArea();
}
}
else if (Tag == 0x02)
{
//模式0x02,说明国家信息是一个偏移位置
country_Offset = GetOffset();
//先读取地区信息
area = ReadArea();
//读取国家信息
FileStrm.Seek(country_Offset, SeekOrigin.Begin);
country = ReadString();
}
else
{
//这种模式最简单了,直接读取国家和地区就OK了
FileStrm.Seek(-1, SeekOrigin.Current);
country = ReadString();
area = ReadArea();
}
string Address = country + " " + area;
return Address;
}
private UInt32 GetOffset()
{
byte[] TempByte4 = new byte[4];
TempByte4[0] = (byte)FileStrm.ReadByte();
TempByte4[1] = (byte)FileStrm.ReadByte();
TempByte4[2] = (byte)FileStrm.ReadByte();
TempByte4[3] = 0;
return BitConverter.ToUInt32(TempByte4, 0);
}
protected string ReadArea()
{
byte Tag = GetTag();
if (Tag == 0x01 || Tag == 0x02)
{
FileStrm.Seek(GetOffset(), SeekOrigin.Begin);
return ReadString();
}
else
{
FileStrm.Seek(-1, SeekOrigin.Current);
return ReadString();
}
}
protected string ReadString()
{
UInt32 Offset = 0;
byte[] TempByteArray = new byte[256];
TempByteArray[Offset] = (byte)FileStrm.ReadByte();
while (TempByteArray[Offset] != 0x00)
{
Offset += 1;
TempByteArray[Offset] = (byte)FileStrm.ReadByte();
}
return System.Text.Encoding.Default.GetString(TempByteArray).TrimEnd('\0');
}
protected byte GetTag()
{
return (byte)FileStrm.ReadByte();
}
protected CZ_INDEX_INFO IndexInfoAtPos(UInt32 Index_Pos)
{
CZ_INDEX_INFO Index_Info = new CZ_INDEX_INFO();
//根据索引编号计算出在文件中在偏移位置
FileStrm.Seek(Index_Set + 7 * Index_Pos, SeekOrigin.Begin);
Index_Info.IpSet = GetUInt32();
Index_Info.Offset = GetOffset();
FileStrm.Seek(Index_Info.Offset, SeekOrigin.Begin);
Index_Info.IpEnd = GetUInt32();
return Index_Info;
}
/// <summary>
/// 从IP转换为Int32
/// </summary>
/// <param name="IpValue"></param>
/// <returns></returns>
public UInt32 IPToUInt32(string IpValue)
{
string[] IpByte = IpValue.Split('.');
Int32 nUpperBound = IpByte.GetUpperBound(0);
if (nUpperBound != 3)
{
IpByte = new string[4];
for (Int32 i = 1; i <= 3 - nUpperBound; i++)
IpByte[nUpperBound + i] = "0";
}
byte[] TempByte4 = new byte[4];
for (Int32 i = 0; i <= 3; i++)
{
//'如果是.Net 2.0可以支持TryParse。
//'If Not (Byte.TryParse(IpByte(i), TempByte4(3 - i))) Then
//' TempByte4(3 - i) = &H0
//'End If
if (IsNumeric(IpByte[i]))
TempByte4[3 - i] = (byte)(Convert.ToInt32(IpByte[i]) & 0xff);
}
return BitConverter.ToUInt32(TempByte4, 0);
}
/// <summary>
/// 判断是否为数字
/// </summary>
/// <param name="str">待判断字符串</param>
/// <returns></returns>
protected bool IsNumeric(string str)
{
if (str != null && System.Text.RegularExpressions.Regex.IsMatch(str, @"^-?\d+$"))
return true;
else
return false;
}
protected UInt32 GetUInt32()
{
byte[] TempByte4 = new byte[4];
FileStrm.Read(TempByte4, 0, 4);
return BitConverter.ToUInt32(TempByte4, 0);
}
}
}

需要用到IP数据库,在打包中有。打包下载http://wt.ruanchen.com/00810/others/iptoaddress.rar