用户信息表,是大多数系统都有的。我们也知道,通常都会有类似 注册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的组件类,如下:
代码
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 }
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 ///
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 文件,如下:
代码
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 }
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的用户信息,如下:
代码
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 >
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地址段了。
运行一下,看看效果吧。