c#实现根据网络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地址段了。
运行一下,看看效果吧.

(0)

相关推荐

  • JS中引用百度地图并将百度地图的logo和信息去掉

    采用CSS覆盖的方法就可以了,但是官方是不允许这么做的,参考:http://developer.baidu.com/map/question.htm 复制代码 代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>javascript移除百度地图LOGO和版权信息</title> <script type="text/j

  • java调用百度定位api服务获取地理位置示例

    复制代码 代码如下: package test; import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.Reader;import java.net.URL;import java.nio.charset.Charset; import org.json.JSONException;imp

  • 通过百度地图获取公交线路的站点坐标的js代码

    最近做百度地图的模拟数据,需要获取某条公交线路沿途站点的坐标信息,貌似百度没有现成的API,因此做了一个模拟页面,工具而已,IE6/7/8不支持 复制代码 代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>获取公交站点坐标</title> <style type="text/css"> html,b

  • 百度地图api应用标注地理位置信息(js版)

    有时做了一些东西没有记录,而过一段时间再看的时候,有会忘记了.需要在重新在看一遍. 百度地图javascript api可以参考 http://developer.baidu.com/map/reference/  示例:http://developer.baidu.com/map/jsdemo.htm 更多百度地图的介绍http://www.cnblogs.com/milkmap/tag/%E5%9C%B0%E5%9B%BEAPI/   里面介绍的非常详细. 弄了一个百度地图来标注地理位置信息

  • Android下如何使用百度地图sdk

    可以使用该套 SDK开发适用于Android系统移动设备的地图应用,通过调用地图SDK接口,您可以轻松访问百度地图服务和数据,构建功能丰富.交互性强的LBS(地图类)应用程序. 百度地图Android SDK提供的所有服务是免费的,接口使用无次数限制.您需申请密钥(key)后,才可使用百度地图Android SDK.任何非营利性产品请直接使用.这弦外之音就是盈利的产品必须帮百度给钱. 一.百度地图api平台. 百度地图API网址:http://developer.baidu.com/map/sd

  • 用Android Location获取当前地理位置的方法

    在Android应用中,往往有获取当前地理位置的需求,比如微信获取附近的人需要获取用户当前的位置,不多说,直接上例子. 复制代码 代码如下: public Location getLocation() {// 获取Location通过LocationManger获取!  LocationManager locManger = (LocationManager) getSystemService(Context.LOCATION_SERVICE);  Location loc = locMange

  • 利用百度地图JSAPI生成h7n9禽流感分布图实现代码

    下图为使用百度地图JSAPI生成的H7N9感染分布图示例,其中的数据来自新华网(4.8号),截图如下: 使用的功能列表如下: 1.自定义版权控件功能,即(1)对应的数据来源部分,代码如下: 复制代码 代码如下: var cr = new BMap.CopyrightControl({anchor: BMAP_ANCHOR_TOP_RIGHT}); map.addControl(cr); //添加版权控件 var bs = map.getBounds(); cr.addCopyright({id:

  • 如何在一个页面显示多个百度地图

    以下是在页面加入两个地图的效果: 页面核心代码如下: 复制代码 代码如下: <style type="text/css">#mapDiv1 { height:400px; width:600px; }#mapDiv2 { height:400px; width:600px; left:620px; top:-420px;}</style><body><div id="mapDiv1" ></div><

  • ios百度地图的使用(普通定位、反地理编码)

    iOS定位 - 普通定位(没有地图) - 反地理编码(得到具体位置),下面通过代码给大家详解,代码如下: #import <CoreLocation/CoreLocation.h> 使用到的头文件 要引入CoreLocation这个包 <CLLocationManagerDelegate> 使用的代理名称 //1.使用定位服务 //设置app有访问定位服务的权限 //在使用应用期间 / 始终(app在后台) //info.plist文件添加以下两条(或者其中一条): //NSLoc

  • c#通过ip获取地理信息

    复制代码 代码如下: /// <summary>      /// 通过IP得到IP所在地省市(Porschev)      /// </summary>      /// <param name="ip"></param>      /// <returns></returns>      public string GetAdrByIp(string ip)      {          string url

随机推荐