IpHelper根据客户端IP进行网站分流
public class IpHelper
{
// 核心方法:IP搜索
/// <summary>
/// 查找IP所属地区,确保web.config存在IPData或者BackIpData配置节
/// </summary>
/// <param name="ips">IP</param>
/// <returns></returns>
public static IpLocation GetIpLocation(string ips)
{
string fn =HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["IPData"]);
string backData = HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["BackIpData"]);
if (!File.Exists(fn))
{
if (!File.Exists(backData))
{
throw new Exception("文件不存在");
}
fn = backData;
}
FileStream fs = new FileStream(fn, FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryReader fp = new BinaryReader(fs);
//读文件头,获取首末记录偏移量
int fo = fp.ReadInt32();
int lo = fp.ReadInt32();
//IP值
uint ipv = IpStringToInt(ips);
// 获取IP索引记录偏移值
int rcOffset = getIndexOffset(fs, fp, fo, lo, ipv);
fs.Seek(rcOffset, System.IO.SeekOrigin.Begin);
IpLocation ipl;
if (rcOffset >= 0)
{
fs.Seek(rcOffset, System.IO.SeekOrigin.Begin);
//读取开头IP值
ipl.IpStart = fp.ReadUInt32();
//转到记录体
fs.Seek(ReadInt24(fp), System.IO.SeekOrigin.Begin);
//读取结尾IP值
ipl.IpEnd = fp.ReadUInt32();
ipl.Country = GetString(fs, fp);
ipl.City = GetString(fs, fp);
}
else
{
//没找到
ipl.IpStart = 0;
ipl.IpEnd = 0;
ipl.Country = "未知国家";
ipl.City = "未知地址";
}
fp.Close();
fs.Close();
return ipl;
}
// 函数功能: 采用“二分法”搜索索引区, 定位IP索引记录位置
private static int getIndexOffset(FileStream fs, BinaryReader fp, int _fo, int _lo, uint ipv)
{
int fo = _fo, lo = _lo;
int mo; //中间偏移量
uint mv; //中间值
uint fv, lv; //边界值
uint llv; //边界末末值
fs.Seek(fo, System.IO.SeekOrigin.Begin);
fv = fp.ReadUInt32();
fs.Seek(lo, System.IO.SeekOrigin.Begin);
lv = fp.ReadUInt32();
//临时作它用,末记录体偏移量
mo = ReadInt24(fp);
fs.Seek(mo, System.IO.SeekOrigin.Begin);
llv = fp.ReadUInt32();
//边界检测处理
if (ipv < fv)
return -1;
else if (ipv > llv)
return -1;
//使用"二分法"确定记录偏移量
do
{
mo = fo + (lo - fo) / 7 / 2 * 7;
fs.Seek(mo, System.IO.SeekOrigin.Begin);
mv = fp.ReadUInt32();
if (ipv >= mv)
fo = mo;
else
lo = mo;
if (lo - fo == 7)
mo = lo = fo;
} while (fo != lo);
return mo;
}
// 字符串数值型判断
public static bool IsNumeric(string s)
{
if (s != null && System.Text.RegularExpressions.Regex.IsMatch(s, @"^-?\d+$"))
return true;
else
return false;
}
// IP字符串->长整型值
public static uint IpStringToInt(string IpString)
{
uint Ipv = 0;
string[] IpStringArray = IpString.Split('.');
int i;
uint Ipi;
for (i = 0; i < 4 && i < IpStringArray.Length; i++)
{
if (IsNumeric(IpStringArray[i]))
{
Ipi = (uint)Math.Abs(Convert.ToInt32(IpStringArray[i]));
if (Ipi > 255) Ipi = 255;
Ipv += Ipi << (3 - i) * 8;
}
}
return Ipv;
}
// 长整型值->IP字符串
public static string IntToIpString(uint Ipv)
{
string IpString = "";
IpString += (Ipv >> 24) + "." + ((Ipv & 0x00FF0000) >> 16) + "." + ((Ipv & 0x0000FF00) >> 8) + "." + (Ipv & 0x000000FF);
return IpString;
}
// 读取字符串
private static string ReadString(BinaryReader fp)
{
byte[] TempByteArray = new byte[128];
int i = 0;
do
{
TempByteArray[i] = fp.ReadByte();
} while (TempByteArray[i++] != '\0' && i < 128);
return System.Text.Encoding.Default.GetString(TempByteArray).TrimEnd('\0');
}
// 读取三字节的整数
private static int ReadInt24(BinaryReader fp)
{
if (fp == null) return -1;
int ret = 0;
ret |= (int)fp.ReadByte();
ret |= (int)fp.ReadByte() << 8 & 0xFF00;
ret |= (int)fp.ReadByte() << 16 & 0xFF0000;
return ret;
}
// 读取IP所在地字符串
private static string GetString(FileStream fs, BinaryReader fp)
{
byte Tag;
int Offset;
Tag = fp.ReadByte();
if (Tag == 0x01) // 重定向模式1: 城市信息随国家信息定向
{
Offset = ReadInt24(fp);
fs.Seek(Offset, System.IO.SeekOrigin.Begin);
return GetString(fs, fp);
}
else if (Tag == 0x02) // 重定向模式2: 城市信息没有随国家信息定向
{
Offset = ReadInt24(fp);
int TmpOffset = (int)fs.Position;
fs.Seek(Offset, System.IO.SeekOrigin.Begin);
string TmpString = GetString(fs, fp);
fs.Seek(TmpOffset, System.IO.SeekOrigin.Begin);
return TmpString;
}
else // 无重定向: 最简单模式
{
fs.Seek(-1, System.IO.SeekOrigin.Current);
return ReadString(fp);
}
}
}
// IP查询结果结构
public struct IpLocation
{
public uint IpStart;
public uint IpEnd;
/// <summary>
/// 国家或城市
/// </summary>
public string Country;
/// <summary>
/// 城市或详细地址
/// </summary>
public string City;
}
IpHelper根据客户端IP进行网站分流的更多相关文章
- C#服务器获取客户端IP地址以及归属地探秘
背景:博主本是一位Windows桌面应用程序开发工程师,对网络通信一知半解.一日老婆逛完某宝,问:"为什么他们知道我的地址呢,他们是怎么获取我的地址的呢?" 顺着这个问题我们的探秘 ...
- 用javascript得到客户端IP的新方法
javascript得到客户端IP的新方法 很久以来,我都是经过http://fw.qq.com/ipaddress来得到客户端用户的IP,这个方法简单.快速.实用 . 我们调用它的写法是: < ...
- .net通过获取客户端IP地址反查出用户的计算机名
这个功能看似很少用到,但又非常实用,看似简单,但又在其中存在很多未知因素造成让人悲痛莫名的负能量... 这是公司内部最近在使用的功能,因为是DHCP,所以有时会根据计算机名做一些统计和权限的设置. 也 ...
- 学习笔记_过滤器应用_1(分ip统计网站的访问次数)
分ip统计网站的访问次数 ip count 192.168.1.111 2 192.168.1.112 59 统计工作需要在所有资源之前都执行,那么就可以放到Filter中了. 我们这个过滤器不打算做 ...
- Java web 实现 之 Filter分析ip统计网站的访问次数
统计工作需要在所有资源之前都执行,那么就可以放到Filter中了. 我们这个过滤器不打算做拦截操作!因为我们只是用来做统计的. 用什么东西来装载统计的数据.Map<String,Integer& ...
- JS获取客户端IP地址、MAC和主机名七种方法
一.使用JS获取客户端IP的几个方法方法一(只针对IE且客户端的IE允许AcitiveX运行,通过平台:XP,SERVER03,2000).获取客户端IP代码:<HTML><HEAD ...
- C# WebApi 获取客户端ip地址
转自:http://www.cnblogs.com/weixing/p/5674078.html References required: HttpContextWrapper - System.We ...
- JS获取客户端IP地址、MAC和主机名的7个方法汇总
今天在搞JS(javascript)获取客户端IP的小程序,上网搜了下,好多在现在的系统和浏览器中的都无效,很无奈,在Chrome.FireFox中很少搞到直接利用ActiveX获取IP等的JS脚本. ...
- WebService(JAX-WS、XFire、Axis三种)获取客户端ip
WebService(JAX-WS.XFire.Axis三种)获取客户端ip JAX-WS.XFire.Axis三种webservice的获取客户端IP的简单实现过程: 1,基于JDK6 jax-ws ...
随机推荐
- VBA 中窗体模式切换,一次设计2种表现
Sub ModelChange() Then DoCmd.RunCommand acCmdSubformFormView ''''就这句 Me.Form.AllowEdits = True ' Mod ...
- Fiddler屏蔽某些url的抓取方法
在用Fiddler调试网页的时候,可能某些频繁的ajax轮询请求会干扰我们,可以通过以下方法屏蔽某些url的抓取. 在需要屏蔽的url行上右键---->“Filter Now”-----> ...
- apache一个IP一个端口对应多个域名
一个IP一个端口对应多个域名: NameVirtualHost XXX.XXX.XXX.XXX:80 <VirtualHost XXX.XXX.XXX.XXX:80> ServerAdmi ...
- python Synchronization between processes
进程间同步,可以使用lock进行控制. 官方文档的例子如下: from multiprocessing import Process, Lock def f(l, i): l.acquire() pr ...
- ZOJ 1489 HDU1395 2^x mod n = 1 数学
2^x mod n = 1 Time Limit: 2 Seconds Memory Limit:65536 KB Give a number n, find the minimum x t ...
- Struts2 02--通配符
在以前没有使用Struts时,web与前台的数据交互通过Servlet+jsp页面.一个增删改查往往需要写四个Servlet来处理数据:在使用struts之后,Servlet不再被使用,而是通过 ...
- 移动端自动化自动化(Android&iOS)——Appium
Appium-Python 移动端自动化环境搭建 Appium介绍 Appium是一个开源.跨平台的测试框架,可以用来测试原生及混合的移动端应用.Appium支持iOS.Android及Firefox ...
- Ubuntu安装Flash视频插件
http://www.linuxidc.com/Linux/2014-05/101095.htm
- MySQL简概
MySQL简介与概要 mysql 是一个小型关系型数据库管理系统,开发者为瑞典MySQL AB公司,现在已经被sun公司收购,支持FreeBSD.Linux.MAC.windows等多种操作系统.相比 ...
- Python练习----多级菜单
多级菜单要求: 1.三级菜单 2.可依次选择进入各子菜单 3.可以返回上一层 4.输入'q'可以退出 脚本: zone = { '北京' : { ' ...