• 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++] != '' && i < 128);
                return System.Text.Encoding.Default.GetString(TempByteArray).TrimEnd('');
            }
            // 读取三字节的整数
            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;
       }

  • 相关阅读:
    python常用函数 A
    从__name__=='__main__'说到__builtin__
    python常用魔法函数
    MySQL内核:InnoDB存储引擎 卷1
    “胡”说IC——菜鸟工程师完美进阶
    恶意代码分析实战
    转折点:移动互联网时代的商业法则
    大型网站系统与Java中间件实践
    《Node.js实战(双色)》作者之一——吴中骅访谈录
    网站运维技术与实践
  • 原文地址:https://www.cnblogs.com/wwwzzg168/p/3570719.html
Copyright © 2020-2023  润新知