视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
c#实现根据网络IP显示地理位置功能示例
2020-11-27 22:40:52 责编:小采
文档


用户信息表,是大多数系统都有的。我们也知道,通常都会有类似 注册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(".0.0.0")) && (intIP <= IpToInt("126.255.255.255")))) ||
//((intIP >= IpToInt("58.0.0.0")) && (intIP <= IpToInt("60.255.255.255"))))
//if (intIP <= 503317 || (intIP >= 1073741824 && intIP <= 21307031) || (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地址段了。
运行一下,看看效果吧.

下载本文
显示全文
专题