using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Web;
namespace Ticket.WebServices.CNTicket
{
public class IPService
{
#region "成员变量"
private Stream dbStream;
private uint ipCount = 0;
private uint indexPos = 0;//索引区开始位置
private static object helper = new object();
private static CNTicket.IPService service = null;
#endregion
#region "成员方法"
/// <summary>
/// 实例化
/// </summary>
/// <returns></returns>
public static CNTicket.IPService GetInstance()
{
if (service == null)
{
lock (helper)
{
if (service == null)
{
service = new IPService();
}
}
}
return service;
}
/// <summary>
/// 查找国家
/// </summary>
/// <param name="stream">数据流</param>
/// <returns>国家</returns>
private string GetCountry(Stream stream)
{
byte[] byteArray = new byte[256];
Encoding gb2312 = Encoding.GetEncoding("GB2312");
int count = 0;
while (true)
{
byteArray[count] = (byte)stream.ReadByte();
if (0 == byteArray[count])
break;
count++;
}
char[] charArray = new char[count];
gb2312.GetChars(byteArray, 0, count, charArray, 0);
string result = "";
for (int i = 0; i < charArray.Length && '/0' != (int)charArray[i]; i++)
{
result = result + charArray[i];
}
return result;
}
/// <summary>
/// 从字节转换短整型
/// </summary>
/// <param name="aryLst"></param>
/// <returns></returns>
private uint ConvertByteToUint(byte[] aryLst)
{
uint result = 0;
for (int i = 0; i < aryLst.Length; i++)
{
result = (uint)aryLst[i] * (uint)Math.Pow(256, i) + result;
}
return result;
}
/// <summary>
/// 卸载IP数据库
/// </summary>
private void UnLoadIpDB()
{
if (dbStream != null) dbStream.Close();
}
/// <summary>
/// 加载IP数据库
/// </summary>
/// <param name="fileName">文件名</param>
/// <returns></returns>
private int LoadIpDB(string fileName)
{
int tmp = -1;
if (!File.Exists(fileName))
{
tmp = 0;//文件未找到
}
try
{
dbStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
uint beginInt = 0, endInt = 0;
byte[] bt = new byte[4];
dbStream.Read(bt, 0, 4);
beginInt = ConvertByteToUint(bt);
dbStream.Read(bt, 0, 4);
endInt = ConvertByteToUint(bt);
uint total = endInt - beginInt;
if (total % 7 != 0)
{
tmp = 2;//文件损坏
}
ipCount = total / 7;
ipCount++;
indexPos = beginInt;
}
catch (Exception e)
{
Console.WriteLine("Exception in IpSearcher.loadIpDB(): " + e.Message);
tmp = 1;//无法打开文件
}
return tmp;
}
/// <summary>
/// 获取当前IP
/// </summary>
/// <param name="strIP"></param>
/// <returns></returns>
private uint GetCurrentIp(string strIP)
{
uint iIP = 0;
uint tmpIP = 0;
for (int i = 0; i < strIP.Length; i++)
{
char curChar = strIP[i];
if ('.' == curChar)
{
iIP = 256 * iIP + tmpIP;
tmpIP = 0;
}
else
{
tmpIP = 10 * tmpIP + curChar - '0';
}
}
iIP = 256 * iIP + tmpIP;
return iIP;
}
/// <summary>
/// 根据Ip获取城市
/// </summary>
/// <param name="strIP"></param>
/// <returns></returns>
private string GetCity(string strIP) //61.48.0.0(2) 61.53.27.0 61.131.46.0 3/1026818048/3d.34/61.52
{
string result = "";
if (dbStream != null)
{
uint iIP = GetCurrentIp(strIP);
uint beginPos = 0, endPos = ipCount;
byte[] tmpByte = new byte[4];
while (true)
{
if (beginPos >= endPos - 1)
{
break;
}
dbStream.Position = indexPos + (beginPos + endPos) / 2 * 7;
dbStream.Read(tmpByte, 0, 4);
uint tmpIP = ConvertByteToUint(tmpByte);
if (iIP < tmpIP)
{
endPos = (beginPos + endPos) / 2;
}
else
{
beginPos = (beginPos + endPos) / 2;
}
}
byte[] tmp3Byte = new byte[3];
dbStream.Position = indexPos + 7 * beginPos + 4;
dbStream.Read(tmp3Byte, 0, 3);
uint ipPos = ConvertByteToUint(tmp3Byte);//ipPos要查找的IP纪录的起始位置
dbStream.Position = ipPos;
dbStream.Read(tmpByte, 0, 4);
if (iIP <= ConvertByteToUint(tmpByte))//找到该IP的位置信息
{
uint curPos = ipPos + 4;
if (0x01 == dbStream.ReadByte())
{
dbStream.Read(tmp3Byte, 0, 3);
curPos = ConvertByteToUint(tmp3Byte);
dbStream.Position = curPos;
}
else
{
dbStream.Seek(-1, SeekOrigin.Current);
}
if (0x02 == dbStream.ReadByte())
{
dbStream.Read(tmp3Byte, 0, 3);
curPos = ConvertByteToUint(tmp3Byte);
dbStream.Position = curPos;
}
else
{
dbStream.Seek(-1, SeekOrigin.Current);
}
//找到国家
result = GetCountry(dbStream);
}
else
{
result = "未知数据";
}
}
return result;
}
/// <summary>
/// 获取IP和城市
/// </summary>
/// <returns></returns>
public string GetIpAndCity()
{
LoadIpDB(HttpContext.Current.Server.MapPath("QQWry.dat"));
string ipCity = GetCity(HttpContext.Current.Request.UserHostAddress.ToString());
UnLoadIpDB();
string regcity = "";
///通过注册信息城市检测
if (HttpContext.Current.Session["userId"] != null)
{
regcity = "";//Data.User.GetInstance().GetCity(Convert.ToString(HttpContext.Current.Session["userId"]));
}
return ipCity + "-" + regcity;
}
/// <summary>
/// 根据IP查找所属城市
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public string GetCityByIp(string ip)
{
string ipCity = "";
LoadIpDB(HttpContext.Current.Server.MapPath("QQWry.dat"));
ipCity = GetCity(ip);
UnLoadIpDB();
return ipCity;
}
#endregion
}
}