您的位置:首页 > 理论基础 > 计算机网络

c#实现根据网络IP显示地理位置功能

2013-06-23 20:52 876 查看
用户信息表,是大多数系统都有的。我们也知道,通常都会有类似 注册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 /// <summary>

142 /// Gets the country.

143 /// </summary>

144 /// <param name="endIpOff">The end ip off.</param>

145 /// <param name="countryFlag">The country flag.</param>

146 /// <param name="local">The local.</param>

147 /// <returns>country</returns>

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 /// <summary>

194 /// 读取字符串...

195 /// </summary>

196 /// <param name="offset"></param>

197 /// <returns></returns>

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 /// <summary>

13 /// IP查询 的摘要说明

14 /// </summary>

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>



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

运行一下,看看效果吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: