后台增加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的组件类,如下:

ExpandedBlockStart.gif 代码
  1  using  System;
  2  using  System.Collections.Generic;
  3  using  System.Text;
  4  using  System.IO;
  5  using  System.Text.RegularExpressions;
  6  using  System.Net;
  7  using  System.Net.Sockets;
  8 
  9  namespace  AjaxIP
 10  {
 11       public   class  IPLocation
 12      {
 13           public   string  IP {  get set ; }
 14           public   string  Country {  get set ; }
 15           public   string  Local {  get set ; }
 16      }
 17 
 18       public   class  QQWryLocator
 19      {
 20           static  Encoding encoding  =  Encoding.GetEncoding( " GB2312 " );
 21 
 22           private   byte [] data;
 23           int  firstStartIpOffset;
 24           int  lastStartIpOffset;
 25           int  ipCount;
 26 
 27           public   int  Count {  get  {  return  ipCount; } }
 28 
 29           public  QQWryLocator( string  dataPath)
 30          {
 31               using  (FileStream fs  =   new  FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read))
 32              {
 33                  data  =   new   byte [fs.Length];
 34                  fs.Read(data,  0 , data.Length);
 35              }
 36 
 37              firstStartIpOffset  =  ( int )data[ 0 +  ((( int )data[ 1 ])  <<   8 +  ((( int )data[ 2 ])  <<   16 +  ((( int )data[ 3 ])  <<   24 );
 38              lastStartIpOffset  =  ( int )data[ 4 +  ((( int )data[ 5 ])  <<   8 +  ((( int )data[ 6 ])  <<   16 +  ((( int )data[ 7 ])  <<   24 );
 39              ipCount  =  (lastStartIpOffset  -  firstStartIpOffset)  /   7   +   1 ;
 40 
 41               if  (ipCount  <=   1 )
 42              {
 43                   throw   new  ArgumentException( " ip FileDataError " );
 44              }
 45          }
 46 
 47           public   static   uint  IpToInt( string  ip)
 48          {
 49               // string[] strArray = ip.Split('.');
 50               // return (uint.Parse(strArray[0]) << 24) + (uint.Parse(strArray[1]) << 16) + (uint.Parse(strArray[2]) << 8) + uint.Parse(strArray[0]);
 51               // return (uint)IPAddress.HostToNetworkOrder((int)(IPAddress.Parse(ip).Address));
 52 
 53               byte [] bytes  =  IPAddress.Parse(ip).GetAddressBytes();
 54               return  ( uint )bytes[ 3 +  ((( uint )bytes[ 2 ])  <<   8 +  ((( uint )bytes[ 1 ])  <<   16 +  ((( uint )bytes[ 0 ])  <<   24 );
 55          }
 56 
 57           public   static   string  IntToIP( uint  ip_Int)
 58          {
 59               return   new  IPAddress(ip_Int).ToString();
 60          }
 61 
 62           public  IPLocation Query( string  ip)
 63          {
 64              IPAddress address  =  IPAddress.Parse(ip);
 65               if  (address.AddressFamily  !=  AddressFamily.InterNetwork)
 66              {
 67                   throw   new  ArgumentException( " 不支持非IPV4的地址 " );
 68              }
 69 
 70               if  (IPAddress.IsLoopback(address))
 71              {
 72                   return   new  IPLocation() { IP  =  ip, Country  =   " 本机内部环回地址 " , Local  =   string .Empty };
 73              }
 74 
 75               uint  intIP  =  ( uint )IPAddress.HostToNetworkOrder(( int )address.Address);
 76 
 77               // 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")))) ||
 78               // ((intIP >= IpToInt("58.0.0.0")) && (intIP <= IpToInt("60.255.255.255"))))
 79               // if (intIP <= 50331647 || (intIP >= 1073741824 && intIP <= 2130706431) || (intIP >= 973078528 && intIP <= 1023410175))
 80               // {
 81               //     return new IPLocation() { IP = ip, Country = "网络保留地址", Local = string.Empty };
 82               // }
 83 
 84              IPLocation ipLocation  =   new  IPLocation() { IP  =  ip };
 85 
 86               uint  right  =  ( uint )ipCount;
 87               uint  left  =   0 ;
 88               uint  middle  =   0 ;
 89               uint  startIp  =   0 ;
 90               uint  endIpOff  =   0 ;
 91               uint  endIp  =   0 ;
 92               int  countryFlag  =   0 ;
 93 
 94               while  (left  <  (right  -   1 ))
 95              {
 96                  middle  =  (right  +  left)  /   2 ;
 97                  startIp  =  GetStartIp(middle,  out  endIpOff);
 98                   if  (intIP  ==  startIp)
 99                  {
100                      left  =  middle;
101                       break ;
102                  }
103                   if  (intIP  >  startIp)
104                  {
105                      left  =  middle;
106                  }
107                   else
108                  {
109                      right  =  middle;
110                  }
111              }
112              startIp  =  GetStartIp(left,  out  endIpOff);
113              endIp  =  GetEndIp(endIpOff,  out  countryFlag);
114               if  ((startIp  <=  intIP)  &&  (endIp  >=  intIP))
115              {
116                   string  local;
117                  ipLocation.Country  =  GetCountry(endIpOff, countryFlag,  out  local);
118                  ipLocation.Local  =  local;
119              }
120               else
121              {
122                  ipLocation.Country  =   " 未知 " ;
123                  ipLocation.Local  =   string .Empty;
124              }
125               return  ipLocation;
126          }
127 
128           private   uint  GetStartIp( uint  left,  out   uint  endIpOff)
129          {
130               int  leftOffset  =  ( int )(firstStartIpOffset  +  (left  *   7 ));
131              endIpOff  =  ( uint )data[ 4   +  leftOffset]  +  ((( uint )data[ 5   +  leftOffset])  <<   8 +  ((( uint )data[ 6   +  leftOffset])  <<   16 );
132               return  ( uint )data[leftOffset]  +  ((( uint )data[ 1   +  leftOffset])  <<   8 +  ((( uint )data[ 2   +  leftOffset])  <<   16 +  ((( uint )data[ 3   +  leftOffset])  <<   24 );
133          }
134 
135           private   uint  GetEndIp( uint  endIpOff,  out   int  countryFlag)
136          {
137              countryFlag  =  data[ 4   +  endIpOff];
138               return  ( uint )data[endIpOff]  +  ((( uint )data[ 1   +  endIpOff])  <<   8 +  ((( uint )data[ 2   +  endIpOff])  <<   16 +  ((( uint )data[ 3   +  endIpOff])  <<   24 );
139          }
140 
141           ///  
142           ///  Gets the country.
143           ///  

144           ///   The end ip off.
145           ///   The country flag.
146           ///   The local.
147           ///   country
148           private   string  GetCountry( uint  endIpOff,  int  countryFlag,  out   string  local)
149          {
150               string  country  =   string .Empty;
151               uint  offset  =  endIpOff  +   4 ;
152               switch  (countryFlag)
153              {
154                   case   1 :
155                   case   2 :
156                      country  =  GetFlagStr( ref  offset,  ref  countryFlag,  ref  endIpOff);
157                      offset  =  endIpOff  +   8 ;
158                      local  =  ( 1   ==  countryFlag)  ?   string .Empty : GetFlagStr( ref  offset,  ref  countryFlag,  ref  endIpOff);
159                       break ;
160                   default :
161                      country  =  GetFlagStr( ref  offset,  ref  countryFlag,  ref  endIpOff);
162                      local  =  GetFlagStr( ref  offset,  ref  countryFlag,  ref  endIpOff);
163                       break ;
164              }
165               return  country;
166          }
167 
168           private   string  GetFlagStr( ref   uint  offset,  ref   int  countryFlag,  ref   uint  endIpOff)
169          {
170               int  flag  =   0 ;
171               while  ( true )
172              {
173                  flag  =  data[offset];
174                   // 没有重定向
175                   if  (flag  !=   1   &&  flag  !=   2 )
176                  {
177                       break ;
178                  }
179                   if  (flag  ==   2 )
180                  {
181                      countryFlag  =   2 ;
182                      endIpOff  =  offset  -   4 ;
183                  }
184                  offset  =  ( uint )data[ 1   +  offset]  +  ((( uint )data[ 2   +  offset])  <<   8 +  ((( uint )data[ 3   +  offset])  <<   16 );
185              }
186               if  (offset  <   12 )
187              {
188                   return   string .Empty;
189              }
190               return  GetStr( ref  offset);
191          }
192 
193           ///  
194           ///  读取字符串...
195           ///  

196           ///  
197           ///  
198           private   string  GetStr( ref   uint  offset)
199          {
200               byte  lowByte  =   0 ;
201               byte  highByte  =   0 ;
202              StringBuilder stringBuilder  =   new  StringBuilder( 16 );
203               while  ( true )
204              {
205                  lowByte  =  data[offset ++ ];
206                   if  (lowByte  ==   0 )
207                  {
208                       return  stringBuilder.ToString();
209                  }
210 
211                   if  (lowByte  >   0x7f )
212                  {
213                      highByte  =  data[offset ++ ];
214                       if  (highByte  ==   0 )
215                      {
216                           return  stringBuilder.ToString();
217                      }
218                      stringBuilder.Append(encoding.GetString( new   byte [] { lowByte, highByte }));
219                  }
220                   else
221                  {
222                      stringBuilder.Append(( char )lowByte);
223                  }
224              }
225          }
226      }
227  }

 再来新建 IPSearch.ashx 文件,如下:

ExpandedBlockStart.gif 代码
 1  using  System;
 2  using  System.Collections;
 3  using  System.Data;
 4  using  System.Linq;
 5  using  System.Web;
 6  using  System.Web.Services;
 7  using  System.Web.Services.Protocols;
 8  using  System.Xml.Linq;
 9 
10  namespace  AjaxIP
11  {
12       ///  
13       ///  IP查询 的摘要说明
14       ///  

15       public   class  IPSearch : IHttpHandler
16      {
17 
18           public   void  ProcessRequest(HttpContext context)
19          {
20              context.Response.ContentType  =   " text/plain " ;
21               string  ip  =  context.Request[ " ip " ];
22               string  ipFilePath  =   @" \App_Data\QQWry.dat " ;
23              QQWryLocator QQWry  =   new  QQWryLocator(ipFilePath);
24              IPLocation loc  =  QQWry.Query(ip);
25 
26              context.Response.Write( string .Format( " {0} {1} " ,loc.Country,loc.Local));
27          }
28 
29           public   bool  IsReusable
30          {
31               get
32              {
33                   return   false ;
34              }
35          }
36      }
37  }

最后在Default.aspx页面写下,js和有IP的用户信息,如下:

ExpandedBlockStart.gif 代码
 1  DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
 2 
 3  < html  xmlns ="http://www.w3.org/1999/xhtml"   >
 4  < head  runat ="server" >
 5       < title > title >
 6  < script  language ="javascript"  src ="Js/jquery-1.3.1.js" > script >
 7  < script  language ="javascript" >
 8      $(document).ready( function () {
 9          $( " #tb tr " ).each( function () {
10               var  obj  =  $( this ).children( " td:eq(2) " );
11              SearchIP(obj);
12          });
13      })
14 
15       function  SearchIP(obj) {
16      $.ajax({
17          type:  " GET " ,
18          url:  " IPSearch.ashx?ip= "   +  obj.text(),
19          success:  function (data) {
20              obj.text(data);
21          }
22      });
23  }
24  script >
25  head >
26  < body >
27       < form  id ="form1"  runat ="server" >
28       < div >
29      
30           < table  id ="tb"  style ="width:100%;" >
31               < thead >
32                   < th > 321321 th >
33                   < th > 321321 th >
34                   < th > 321321 th >
35               thead >  
36               < tr >
37                   < td >
38                      OMEGA td >
39                   < td >
40                      0 td >
41                   < td >
42                      122.229.191.8 td >
43               tr >
44               < tr >
45                   < td >
46                      荒年 td >
47                   < td >
48                      900,000 td >
49                   < td >
50                      110.87.98.30 td >
51               tr >
52               < tr >
53                   < td >
54                      寒妃 td >
55                   < td >
56                      1,854,257,979 td >
57                   < td >
58                      220.188.193.72 td >
59               tr >
60               < tr >
61                   < td >
62                      哈小土 td >
63                   < td >
64                      600,100 td >
65                   < td >
66                      220.188.193.72 td >
67               tr >
68               < tr >
69                   < td >
70                      化妆造型 td >
71                   < td >
72                      400,100 td >
73                   < td >
74                      220.188.193.72 td >
75               tr >
76           table >
77      
78       div >
79       form >
80  body >
81  html >

这样我们的后台用户信息不再是不友好的IP地址段了。

运行一下,看看效果吧。

 

转载于:https://www.cnblogs.com/Kurodo/archive/2010/10/11/1848270.html

你可能感兴趣的:(后台增加IP地理位置显示功能)