123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using System.Net;
- using WingServerCommon.Utilities;
- namespace WingServerCommon.Interfaces.Cache
- {
- /// <summary>
- /// IP 管理接口
- /// </summary>
- public interface IIPManager : IBaseCacheManager<CacheIPInfoDTO>
- {
- /// <summary>
- /// 根据IP获取内存中对应IP段的详细信息
- /// </summary>
- /// <param name="ip">ip</param>
- /// <returns>IP段的详细信息</returns>
- public CacheIPInfoDTO GetIPInfo(string ip);
- /// <summary>
- /// 加载IP段文件
- /// </summary>
- /// <param name="path">文件路径</param>
- public void LoadData(string path);
- }
- /// <summary>
- /// IP 管理类
- /// </summary>
- public class IPManager : CacheManager<CacheIPInfoDTO>, IIPManager
- {
- private List<CacheIPInfoDTO> _ipList = new List<CacheIPInfoDTO>();
- private StartRangeComparer startRangeComparer = new StartRangeComparer();
- /// <summary>
- /// 根据IP获取内存中对应IP段的详细信息
- /// </summary>
- /// <param name="ip"></param>
- /// <returns></returns>
- public CacheIPInfoDTO GetIPInfo(string ip)
- {
- using (new Performance(5, "{0} GetIPInfo {1}", $"{this.GetType().Name}",$"{ip}"))
- {
- var longIP = IpToLong(ip);
- var index = _ipList.BinarySearch(new CacheIPInfoDTO { LongStartIP = longIP }, startRangeComparer);
- int candidateIndex = index >= 0 ? index : (~index) - 1;
- if (candidateIndex < 0)
- {
- return null;
- }
- CacheIPInfoDTO candidate = _ipList[candidateIndex];
- if (candidate.LongEndIP >= longIP)
- {
- return candidate;
- }
- else
- {
- return null;
- };
- }
- }
- /// <summary>
- /// 加载IP段文件
- /// </summary>
- /// <param name="path">文件路径</param>
- public void LoadData(string path)
- {
- List<CacheIPInfoDTO> list = new List<CacheIPInfoDTO>();
- DirectoryInfo dirInfo = new DirectoryInfo(path);
- if (dirInfo != null)
- {
- FileInfo[] fileInfos = dirInfo.GetFiles();
- if (fileInfos != null && fileInfos.Length > 0)
- {
- foreach (var fileInfo in fileInfos)
- {
- using (FileStream fs = new FileStream(fileInfo.FullName, FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite, FileShare.ReadWrite))
- {
- using (StreamReader sr = new StreamReader(fs, System.Text.Encoding.UTF8))
- {
- var json = sr.ReadToEnd();
- if (!string.IsNullOrEmpty(json))
- {
- var contentList = Newtonsoft.Json.JsonConvert.DeserializeObject<List<CacheIPInfoDTO>>(json);
- if (contentList != null && contentList.Count > 0)
- {
- list.AddRange(contentList);
- }
- }
- }
- }
- }
- }
- }
- _ipList = list.OrderBy(v => v.LongStartIP).ToList();
- }
- /// <summary>
- /// ip to long
- /// </summary>
- /// <param name="ip"></param>
- /// <returns></returns>
- private long IpToLong(string ip)
- {
- byte[] byts = IPAddress.Parse(ip).GetAddressBytes();
- Array.Reverse(byts); // 需要倒置一次字节序
- long ipLong = BitConverter.ToUInt32(byts, 0);
- return ipLong;
- }
- }
- public class StartRangeComparer : IComparer<CacheIPInfoDTO>
- {
- public int Compare(CacheIPInfoDTO first, CacheIPInfoDTO second)
- {
- return first.LongStartIP.CompareTo(second.LongStartIP);
- }
- }
- /// <summary>
- /// IP 信息对象类
- /// </summary>
- public class CacheIPInfoDTO : ICacheObject
- {
- /// <summary>
- /// 起始 long 类型IP
- /// </summary>
- /// <value></value>
- public long LongStartIP { get; set; }
- /// <summary>
- /// 结束 long 类型IP
- /// </summary>
- /// <value></value>
- public long LongEndIP { get; set; }
- /// <summary>
- ///纬度
- /// </summary>
- /// <value></value>
- public double Lat { get; set; }
- /// <summary>
- /// 经度
- /// </summary>
- /// <value></value>
- public double Lng { get; set; }
- /// <summary>
- /// 国家
- /// </summary>
- /// <value></value>
- public string Country { get; set; }
- /// <summary>
- ///省
- /// </summary>
- /// <value></value>
- public string Province { get; set; }
- /// <summary>
- ///城市
- /// </summary>
- /// <value></value>
- public string City { get; set; }
- /// <summary>
- ///区县
- /// </summary>
- /// <value></value>
- public string Districts { get; set; }
- /// <summary>
- ///是否中国大陆境内或者境外
- /// </summary>
- /// <value></value>
- public bool IsChinaMainland { get; set; }
- /// <summary>
- ///
- /// </summary>
- /// <value></value>
- public string Code { get; set; }
- }
- }
|