using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
namespace CommonTool
{
public class IpHelper
{
public static IpHelper Instance { get; } = new IpHelper();
///
/// 获取客户端Ip
///
///
public String GetClientIp()
{
String clientIp = "";
if (System.Web.HttpContext.Current != null)
{
clientIp = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (string.IsNullOrEmpty(clientIp) || (clientIp.ToLower() == "unknown"))
{
clientIp = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_REAL_IP"];
if (string.IsNullOrEmpty(clientIp))
{
clientIp = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
}
}
else
{
clientIp = clientIp.Split(',')[0];
}
}
return clientIp;
}
///
/// 服务器端获取客户端请求IP和客户端机器名称
///
public void GetClientInfo()
{
OperationContext context = OperationContext.Current;
MessageProperties messageProperties = context.IncomingMessageProperties;
RemoteEndpointMessageProperty endpointProperty = messageProperties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
HttpRequestMessageProperty requestProperty = messageProperties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
if (endpointProperty != null)
{
string clientIp = !string.IsNullOrEmpty(requestProperty?.Headers["X-Real-IP"]) ? requestProperty.Headers["X-Real-IP"] : endpointProperty.Address;
string clientName = Environment.MachineName;
Console.WriteLine("ClientIp: " + clientIp + "clientName:" + clientName);
}
}
}
#region 根据IP地址获取城市名称
public class IpLocation
{
public string Ip { get; set; }
public string Country { get; set; }
public string Local { get; set; }
}
public class QqWryLocator
{
static readonly Encoding Encoding = Encoding.GetEncoding("GB2312");
private readonly byte[] _data;
readonly int _firstStartIpOffset;
readonly int _ipCount;
public int Count => _ipCount;
public QqWryLocator(string dataPath)
{
dataPath = dataPath ?? FileFuns.GetFullPathFileName("qqwry.dat");
using (FileStream fs = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
_data = new byte[fs.Length];
fs.Read(_data, 0, _data.Length);
}
_firstStartIpOffset = _data[0] + (_data[1] << 8) + ((_data[2]) << 16) + ((_data[3]) << 24);
var lastStartIpOffset = _data[4] + ((_data[5]) << 8) + ((_data[6]) << 16) + ((_data[7]) << 24);
_ipCount = (lastStartIpOffset - _firstStartIpOffset) / 7 + 1;
if (_ipCount <= 1)
{
throw new ArgumentException("ip FileDataError");
}
}
public static uint IpToInt(string ip)
{
//string[] strArray = ip.Split('.');
//return (uint.Parse(strArray[0]) << 24) + (uint.Parse(strArray[1]) << 16) + (uint.Parse(strArray[2]) << 8) + uint.Parse(strArray[0]);
//return (uint)IPAddress.HostToNetworkOrder((int)(IPAddress.Parse(ip).Address));
byte[] bytes = IPAddress.Parse(ip).GetAddressBytes();
return bytes[3] + (((uint)bytes[2]) << 8) + (((uint)bytes[1]) << 16) + (((uint)bytes[0]) << 24);
}
public static string IntToIp(uint ipInt)
{
return new IPAddress(ipInt).ToString();
}
public IpLocation Query(string ip)
{
IPAddress address = IPAddress.Parse(ip);
if (address.AddressFamily != AddressFamily.InterNetwork)
{
throw new ArgumentException("不支持非IPV4的地址");
}
if (IPAddress.IsLoopback(address))
{
return new IpLocation() { Ip = ip, Country = "本机内部环回地址", Local = string.Empty };
}
uint intIp = (uint)IPAddress.HostToNetworkOrder((int)address.Address);
//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")))) ||
//((intIP >= IpToInt("58.0.0.0")) && (intIP <= IpToInt("60.255.255.255"))))
//if (intIP <= 50331647 || (intIP >= 1073741824 && intIP <= 2130706431) || (intIP >= 973078528 && intIP <= 1023410175))
//{
// return new IPLocation() { IP = ip, Country = "网络保留地址", Local = string.Empty };
//}
IpLocation ipLocation = new IpLocation() { Ip = ip };
uint right = (uint)_ipCount;
uint left = 0;
uint startIp;
uint endIpOff;
int countryFlag;
while (left < (right - 1))
{
var middle = (right + left) / 2;
startIp = GetStartIp(middle, out endIpOff);
if (intIp == startIp)
{
left = middle;
break;
}
if (intIp <= startIp)
right = middle;
else
left = middle;
}
startIp = GetStartIp(left, out endIpOff);
var endIp = GetEndIp(endIpOff, out countryFlag);
if ((startIp <= intIp) && (endIp >= intIp))
{
string local;
ipLocation.Country = GetCountry(endIpOff, countryFlag, out local);
ipLocation.Local = local;
}
else
{
ipLocation.Country = "未知";
ipLocation.Local = string.Empty;
}
return ipLocation;
}
private uint GetStartIp(uint left, out uint endIpOff)
{
int leftOffset = (int)(_firstStartIpOffset + (left * 7));
endIpOff = _data[4 + leftOffset] + (((uint)_data[5 + leftOffset]) << 8) + (((uint)_data[6 + leftOffset]) << 16);
return _data[leftOffset] + (((uint)_data[1 + leftOffset]) << 8) + (((uint)_data[2 + leftOffset]) << 16) + (((uint)_data[3 + leftOffset]) << 24);
}
private uint GetEndIp(uint endIpOff, out int countryFlag)
{
countryFlag = _data[4 + endIpOff];
return _data[endIpOff] + (((uint)_data[1 + endIpOff]) << 8) + (((uint)_data[2 + endIpOff]) << 16) + (((uint)_data[3 + endIpOff]) << 24);
}
///
/// Gets the country.
///
/// The end ip off.
/// The country flag.
/// The local.
/// country
private string GetCountry(uint endIpOff, int countryFlag, out string local)
{
string country;
uint offset = endIpOff + 4;
switch (countryFlag)
{
case 1:
case 2:
country = GetFlagStr(ref offset, ref countryFlag, ref endIpOff);
offset = endIpOff + 8;
local = (1 == countryFlag) ? string.Empty : GetFlagStr(ref offset, ref countryFlag, ref endIpOff);
break;
default:
country = GetFlagStr(ref offset, ref countryFlag, ref endIpOff);
local = GetFlagStr(ref offset, ref countryFlag, ref endIpOff);
break;
}
return country;
}
private string GetFlagStr(ref uint offset, ref int countryFlag, ref uint endIpOff)
{
while (true)
{
int flag = _data[offset];
//没有重定向
if (flag != 1 && flag != 2)
{
break;
}
if (flag == 2)
{
countryFlag = 2;
endIpOff = offset - 4;
}
offset = _data[1 + offset] + (((uint)_data[2 + offset]) << 8) + (((uint)_data[3 + offset]) << 16);
}
if (offset < 12)
{
return string.Empty;
}
return GetStr(ref offset);
}
///
/// 读取字符串...
///
///
///
private string GetStr(ref uint offset)
{
StringBuilder stringBuilder = new StringBuilder(16);
while (true)
{
var lowByte = _data[offset++];
if (lowByte == 0)
{
return stringBuilder.ToString();
}
if (lowByte > 0x7f)
{
var highByte = _data[offset++];
if (highByte == 0)
{
return stringBuilder.ToString();
}
stringBuilder.Append(Encoding.GetString(new[] { lowByte, highByte }));
}
else
{
stringBuilder.Append((char)lowByte);
}
}
}
}
#endregion
}