IPScaner.cs 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. using System;
  2. using System.IO;
  3. using System.Web;
  4. namespace CB.Common
  5. {
  6. /// <summary>
  7. /// 从QQWry.Dat中取读IP地址信息
  8. /// </summary>
  9. public class IPScaner
  10. {
  11. private static IPScaner instance = null;
  12. private static FileStream objfs = null;
  13. private static object lockHelper = new object();
  14. #region 私有属性
  15. private long firstStartIp = 0;
  16. private long lastStartIp = 0;
  17. private long startIp = 0;
  18. private long endIp = 0;
  19. private int countryFlag = 0;
  20. private long endIpOff = 0;
  21. private string country;
  22. private string local;
  23. private string ip;
  24. #endregion
  25. private IPScaner(string filePath)
  26. {
  27. if (objfs == null)
  28. {
  29. lock (lockHelper)
  30. {
  31. if (objfs == null)
  32. {
  33. objfs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
  34. }
  35. }
  36. }
  37. }
  38. /// <summary>
  39. /// 单体模式返回当前类的实例
  40. /// </summary>
  41. /// <returns></returns>
  42. public static IPScaner GetIPScanerService(string filePath)
  43. {
  44. if (instance == null)
  45. {
  46. lock (lockHelper)
  47. {
  48. if (instance == null)
  49. {
  50. instance = new IPScaner(filePath);
  51. }
  52. }
  53. }
  54. return instance;
  55. }
  56. #region 私有方法
  57. /// <summary>
  58. /// 获取IP函数
  59. /// </summary>
  60. /// <returns></returns>
  61. private void QQwry()
  62. {
  63. long ip_Int = this.IpToInt(ip);
  64. if (ip_Int >= IpToInt("127.0.0.0") && ip_Int <= IpToInt("127.255.255.255"))
  65. {
  66. this.country = "本机内部环回地址";
  67. this.local = "";
  68. }
  69. else if ((ip_Int >= IpToInt("0.0.0.0") && ip_Int <= IpToInt("2.255.255.255")) || (ip_Int >= IpToInt("64.0.0.0") && ip_Int <= IpToInt("126.255.255.255")) || (ip_Int >= IpToInt("58.0.0.0") && ip_Int <= IpToInt("60.255.255.255")))
  70. {
  71. this.country = "网络保留地址";
  72. this.local = "";
  73. }
  74. if (objfs != null)
  75. {
  76. objfs.Position = 0;
  77. byte[] buff = new Byte[8];
  78. objfs.Read(buff, 0, 8);
  79. firstStartIp = buff[0] + buff[1] * 256 + buff[2] * 256 * 256 + buff[3] * 256 * 256 * 256;
  80. lastStartIp = buff[4] * 1 + buff[5] * 256 + buff[6] * 256 * 256 + buff[7] * 256 * 256 * 256;
  81. long recordCount = Convert.ToInt64((lastStartIp - firstStartIp) / 7.0);
  82. long rangE = recordCount;
  83. long rangB = 0;
  84. long recNO = 0;
  85. while (rangB < rangE - 1)
  86. {
  87. recNO = (rangE + rangB) / 2;
  88. this.GetStartIp(recNO);
  89. if (ip_Int == this.startIp)
  90. {
  91. rangB = recNO;
  92. break;
  93. }
  94. if (ip_Int > this.startIp)
  95. rangB = recNO;
  96. else
  97. rangE = recNO;
  98. }
  99. this.GetStartIp(rangB);
  100. this.GetEndIp();
  101. if (this.startIp <= ip_Int && this.endIp >= ip_Int)
  102. {
  103. this.GetCountry();
  104. this.local = this.local.Replace("(我们一定要解放台湾!!!)", "");
  105. }
  106. else
  107. {
  108. this.country = "未知";
  109. this.local = "";
  110. }
  111. }
  112. else
  113. {
  114. this.country = "";
  115. this.local = "";
  116. }
  117. }
  118. /// <summary>
  119. /// IP地址转换为长整型数据
  120. /// </summary>
  121. /// <param name="ip"></param>
  122. /// <returns></returns>
  123. private long IpToInt(string ip)
  124. {
  125. char[] dot = new char[] { '.' };
  126. string[] ipArr = ip.Split(dot);
  127. if (ipArr.Length == 3)
  128. ip = ip + ".0";
  129. ipArr = ip.Split(dot);
  130. long ip_Int = 0;
  131. long p1 = long.Parse(ipArr[0]) * 256 * 256 * 256;
  132. long p2 = long.Parse(ipArr[1]) * 256 * 256;
  133. long p3 = long.Parse(ipArr[2]) * 256;
  134. long p4 = long.Parse(ipArr[3]);
  135. ip_Int = p1 + p2 + p3 + p4;
  136. return ip_Int;
  137. }
  138. /// <summary>
  139. /// 长整型数据转换为IP地址
  140. /// </summary>
  141. /// <param name="ip_Int"></param>
  142. /// <returns></returns>
  143. private string IntToIP(long ip_Int)
  144. {
  145. long seg1 = (ip_Int & 0xff000000) >> 24;
  146. if (seg1 < 0)
  147. seg1 += 0x100;
  148. long seg2 = (ip_Int & 0x00ff0000) >> 16;
  149. if (seg2 < 0)
  150. seg2 += 0x100;
  151. long seg3 = (ip_Int & 0x0000ff00) >> 8;
  152. if (seg3 < 0)
  153. seg3 += 0x100;
  154. long seg4 = (ip_Int & 0x000000ff);
  155. if (seg4 < 0)
  156. seg4 += 0x100;
  157. string ip = seg1.ToString() + "." + seg2.ToString() + "." + seg3.ToString() + "." + seg4.ToString();
  158. return ip;
  159. }
  160. /// <summary>
  161. /// 获取IP起始部分
  162. /// </summary>
  163. /// <param name="recNO"></param>
  164. /// <returns></returns>
  165. private long GetStartIp(long recNO)
  166. {
  167. long offSet = firstStartIp + recNO * 7;
  168. objfs.Position = offSet;
  169. byte[] buff = new Byte[7];
  170. objfs.Read(buff, 0, 7);
  171. endIpOff = Convert.ToInt64(buff[4].ToString()) + Convert.ToInt64(buff[5].ToString()) * 256 + Convert.ToInt64(buff[6].ToString()) * 256 * 256;
  172. startIp = Convert.ToInt64(buff[0].ToString()) + Convert.ToInt64(buff[1].ToString()) * 256 + Convert.ToInt64(buff[2].ToString()) * 256 * 256 + Convert.ToInt64(buff[3].ToString()) * 256 * 256 * 256;
  173. return startIp;
  174. }
  175. /// <summary>
  176. /// 获取IP结束部分
  177. /// </summary>
  178. /// <returns></returns>
  179. private long GetEndIp()
  180. {
  181. objfs.Position = endIpOff;
  182. byte[] buff = new Byte[5];
  183. objfs.Read(buff, 0, 5);
  184. this.endIp = Convert.ToInt64(buff[0].ToString()) + Convert.ToInt64(buff[1].ToString()) * 256 + Convert.ToInt64(buff[2].ToString()) * 256 * 256 + Convert.ToInt64(buff[3].ToString()) * 256 * 256 * 256;
  185. this.countryFlag = buff[4];
  186. return this.endIp;
  187. }
  188. /// <summary>
  189. /// 获取城市
  190. /// </summary>
  191. /// <returns></returns>
  192. private string GetCountry()
  193. {
  194. switch (this.countryFlag)
  195. {
  196. case 1:
  197. case 2:
  198. this.country = GetFlagStr(this.endIpOff + 4);
  199. this.local = (1 == this.countryFlag) ? " " : this.GetFlagStr(this.endIpOff + 8);
  200. break;
  201. default:
  202. this.country = this.GetFlagStr(this.endIpOff + 4);
  203. this.local = this.GetFlagStr(objfs.Position);
  204. break;
  205. }
  206. return " ";
  207. }
  208. private string GetFlagStr(long offSet)
  209. {
  210. int flag = 0;
  211. byte[] buff = new Byte[3];
  212. while (1 == 1)
  213. {
  214. objfs.Position = offSet;
  215. flag = objfs.ReadByte();
  216. if (flag == 1 || flag == 2)
  217. {
  218. objfs.Read(buff, 0, 3);
  219. if (flag == 2)
  220. {
  221. this.countryFlag = 2;
  222. this.endIpOff = offSet - 4;
  223. }
  224. offSet = Convert.ToInt64(buff[0].ToString()) + Convert.ToInt64(buff[1].ToString()) * 256 + Convert.ToInt64(buff[2].ToString()) * 256 * 256;
  225. }
  226. else
  227. {
  228. break;
  229. }
  230. }
  231. if (offSet < 12)
  232. return " ";
  233. objfs.Position = offSet;
  234. return GetStr();
  235. }
  236. /// <summary>
  237. /// 解码
  238. /// </summary>
  239. /// <returns></returns>
  240. private string GetStr()
  241. {
  242. byte lowC = 0;
  243. byte upC = 0;
  244. string str = "";
  245. byte[] buff = new byte[2];
  246. while (1 == 1)
  247. {
  248. lowC = (Byte)objfs.ReadByte();
  249. if (lowC == 0)
  250. break;
  251. if (lowC > 127)
  252. {
  253. upC = (byte)objfs.ReadByte();
  254. buff[0] = lowC;
  255. buff[1] = upC;
  256. System.Text.Encoding enc = System.Text.Encoding.GetEncoding("GB2312");
  257. str += enc.GetString(buff);
  258. }
  259. else
  260. {
  261. str += (char)lowC;
  262. }
  263. }
  264. return str;
  265. }
  266. #endregion
  267. /// <summary>
  268. /// 返回城市
  269. /// </summary>
  270. /// <returns></returns>
  271. public string IPCountry(string sourceIP)
  272. {
  273. this.ip = sourceIP;
  274. lock (lockHelper)
  275. {
  276. this.QQwry();
  277. }
  278. return this.country;
  279. }
  280. /// <summary>
  281. /// 返回具体地址
  282. /// </summary>
  283. /// <returns></returns>
  284. public string IPLocation(string sourceIP)
  285. {
  286. this.ip = sourceIP;
  287. lock (lockHelper)
  288. {
  289. this.QQwry();
  290. }
  291. return this.country + this.local;
  292. }
  293. }
  294. }