欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

c#实现根据网络IP显示地理位置功能示例

程序员文章站 2024-03-02 11:17:34
用户信息表,是大多数系统都有的。我们也知道,通常都会有类似 注册ip 和 最后登录ip 这两个的字段,来存储用户注册时候的ip地址和最后登录的ip的地址。获取这样的地址,在...
用户信息表,是大多数系统都有的。我们也知道,通常都会有类似 注册ip 和 最后登录ip 这两个的字段,来存储用户注册时候的ip地址和最后登录的ip的地址。

获取这样的地址,在后台显示 xxx.xxx.xxx.xxx 的地址段,让人看到很不自然,根本就不知道具体地理位置。

现在我们就简单的实现一下这个功能。
用到了读取纯真ip数据库的公用组件qqwry.net 这个组件,作者阿不。(谢谢他的共享)
还要去下载最新的纯真ip地址库,下载获得qqwry.dat
最后请出js中的小靓妞,jquery-1.3.1.js
新建web项目ajaxip,将qqwry.dat添加到app_data下。
然后添加qqwry.net的组件类,如下:
复制代码 代码如下:

code highlighting produced by actipro codehighlighter (freeware)http://www.codehighlighter.com/--> 1 using system;
using system.collections.generic;
using system.text;
using system.io;
using system.text.regularexpressions;
using system.net;
using system.net.sockets;
namespace ajaxip
{
public class iplocation
{
public string ip { get; set; }
public string country { get; set; }
public string local { get; set; }
}
public class qqwrylocator
{
static encoding encoding = encoding.getencoding("gb2312");
private byte[] data;
int firststartipoffset;
int laststartipoffset;
int ipcount;
public int count { get { return ipcount; } }
public qqwrylocator(string datapath)
{
using (filestream fs = new filestream(datapath, filemode.open, fileaccess.read, fileshare.read))
{
data = new byte[fs.length];
fs.read(data, 0, data.length);
}
firststartipoffset = (int)data[0] + (((int)data[1]) << 8) + (((int)data[2]) << 16) + (((int)data[3]) << 24);
laststartipoffset = (int)data[4] + (((int)data[5]) << 8) + (((int)data[6]) << 16) + (((int)data[7]) << 24);
ipcount = (laststartipoffset - firststartipoffset) / 7 + 1;
if (ipcount <= 1)
{
throw new argumentexception("ip filedataerror");
}
}
public static uint iptoint(string ip)
{
//string[] strarray = ip.split('.');
//return (uint.parse(strarray[0]) << 24) + (uint.parse(strarray[1]) << 16) + (uint.parse(strarray[2]) << 8) + uint.parse(strarray[0]);
//return (uint)ipaddress.hosttonetworkorder((int)(ipaddress.parse(ip).address));
byte[] bytes = ipaddress.parse(ip).getaddressbytes();
return (uint)bytes[3] + (((uint)bytes[2]) << 8) + (((uint)bytes[1]) << 16) + (((uint)bytes[0]) << 24);
}
public static string inttoip(uint ip_int)
{
return new ipaddress(ip_int).tostring();
}
public iplocation query(string ip)
{
ipaddress address = ipaddress.parse(ip);
if (address.addressfamily != addressfamily.internetwork)
{
throw new argumentexception("不支持非ipv4的地址");
}
if (ipaddress.isloopback(address))
{
return new iplocation() { ip = ip, country = "本机内部环回地址", local = string.empty };
}
uint intip = (uint)ipaddress.hosttonetworkorder((int)address.address);
//if ((((intip >= iptoint("0.0.0.0")) && (intip <= iptoint("2.255.255.255"))) || ((intip >= iptoint("64.0.0.0")) && (intip <= iptoint("126.255.255.255")))) ||
//((intip >= iptoint("58.0.0.0")) && (intip <= iptoint("60.255.255.255"))))
//if (intip <= 50331647 || (intip >= 1073741824 && intip <= 2130706431) || (intip >= 973078528 && intip <= 1023410175))
//{
// return new iplocation() { ip = ip, country = "网络保留地址", local = string.empty };
//}
iplocation iplocation = new iplocation() { ip = ip };
uint right = (uint)ipcount;
uint left = 0;
uint middle = 0;
uint startip = 0;
uint endipoff = 0;
uint endip = 0;
int countryflag = 0;
while (left < (right - 1))
{
middle = (right + left) / 2;
startip = getstartip(middle, out endipoff);
if (intip == startip)
{
left = middle;
break;
}
if (intip > startip)
{
left = middle;
}
else
{
right = middle;
}
}
startip = getstartip(left, out endipoff);
endip = getendip(endipoff, out countryflag);
if ((startip <= intip) && (endip >= intip))
{
string local;
iplocation.country = getcountry(endipoff, countryflag, out local);
iplocation.local = local;
}
else
{
iplocation.country = "未知";
iplocation.local = string.empty;
}
return iplocation;
}
private uint getstartip(uint left, out uint endipoff)
{
int leftoffset = (int)(firststartipoffset + (left * 7));
endipoff = (uint)data[4 + leftoffset] + (((uint)data[5 + leftoffset]) << 8) + (((uint)data[6 + leftoffset]) << 16);
return (uint)data[leftoffset] + (((uint)data[1 + leftoffset]) << 8) + (((uint)data[2 + leftoffset]) << 16) + (((uint)data[3 + leftoffset]) << 24);
}
private uint getendip(uint endipoff, out int countryflag)
{
countryflag = data[4 + endipoff];
return (uint)data[endipoff] + (((uint)data[1 + endipoff]) << 8) + (((uint)data[2 + endipoff]) << 16) + (((uint)data[3 + endipoff]) << 24);
}
/// <summary>
/// gets the country.
/// </summary>
/// <param name="endipoff">the end ip off.</param>
/// <param name="countryflag">the country flag.</param>
/// <param name="local">the local.</param>
/// <returns>country</returns>
private string getcountry(uint endipoff, int countryflag, out string local)
{
string country = string.empty;
uint offset = endipoff + 4;
switch (countryflag)
{
case 1:
case 2:
country = getflagstr(ref offset, ref countryflag, ref endipoff);
offset = endipoff + 8;
local = (1 == countryflag) ? string.empty : getflagstr(ref offset, ref countryflag, ref endipoff);
break;
default:
country = getflagstr(ref offset, ref countryflag, ref endipoff);
local = getflagstr(ref offset, ref countryflag, ref endipoff);
break;
}
return country;
}
private string getflagstr(ref uint offset, ref int countryflag, ref uint endipoff)
{
int flag = 0;
while (true)
{
flag = data[offset];
//没有重定向
if (flag != 1 && flag != 2)
{
break;
}
if (flag == 2)
{
countryflag = 2;
endipoff = offset - 4;
}
offset = (uint)data[1 + offset] + (((uint)data[2 + offset]) << 8) + (((uint)data[3 + offset]) << 16);
}
if (offset < 12)
{
return string.empty;
}
return getstr(ref offset);
}
/// <summary>
/// 读取字符串...
/// </summary>
/// <param name="offset"></param>
/// <returns></returns>
private string getstr(ref uint offset)
{
byte lowbyte = 0;
byte highbyte = 0;
stringbuilder stringbuilder = new stringbuilder(16);
while (true)
{
lowbyte = data[offset++];
if (lowbyte == 0)
{
return stringbuilder.tostring();
}
if (lowbyte > 0x7f)
{
highbyte = data[offset++];
if (highbyte == 0)
{
return stringbuilder.tostring();
}
stringbuilder.append(encoding.getstring(new byte[] { lowbyte, highbyte }));
}
else
{
stringbuilder.append((char)lowbyte);
}
}
}
}
}

再来新建 ipsearch.ashx 文件,如下:
复制代码 代码如下:

code highlighting produced by actipro codehighlighter (freeware)http://www.codehighlighter.com/--> 1 using system;
using system.collections;
using system.data;
using system.linq;
using system.web;
using system.web.services;
using system.web.services.protocols;
using system.xml.linq;
namespace ajaxip
{
/// <summary>
/// ip查询 的摘要说明
/// </summary>
public class ipsearch : ihttphandler
{
public void processrequest(httpcontext context)
{
context.response.contenttype = "text/plain";
string ip = context.request["ip"];
string ipfilepath = @"\app_data\qqwry.dat";
qqwrylocator qqwry = new qqwrylocator(ipfilepath);
iplocation loc = qqwry.query(ip);
context.response.write(string.format("{0} {1}",loc.country,loc.local));
}
public bool isreusable
{
get
{
return false;
}
}
}
}

最后在default.aspx页面写下,js和有ip的用户信息,如下:
复制代码 代码如下:

code highlighting produced by actipro codehighlighter (freeware)http://www.codehighlighter.com/--> 1 <!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
<script language="javascript" src="js/jquery-1.3.1.js"></script>
<script language="javascript">
$(document).ready(function() {
$("#tb tr").each(function() {
var obj = $(this).children("td:eq(2)");
searchip(obj);
});
})
function searchip(obj) {
$.ajax({
type: "get",
url: "ipsearch.ashx?ip=" + obj.text(),
success: function(data) {
obj.text(data);
}
});
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<table id="tb" style="width:100%;">
<thead>
<th>321321</th>
<th>321321</th>
<th>321321</th>
</thead>
<tr>
<td>
omega</td>
<td>
0</td>
<td>
122.229.191.8</td>
</tr>
<tr>
<td>
荒年</td>
<td>
900,000</td>
<td>
110.87.98.30</td>
</tr>
<tr>
<td>
寒妃</td>
<td>
1,854,257,979</td>
<td>
220.188.193.72</td>
</tr>
<tr>
<td>
哈小土</td>
<td>
600,100</td>
<td>
220.188.193.72</td>
</tr>
<tr>
<td>
化妆造型</td>
<td>
400,100</td>
<td>
220.188.193.72</td>
</tr>
</table>
</div>
</form>
</body>
</html>

这样我们的后台用户信息不再是不友好的ip地址段了。
运行一下,看看效果吧.