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 }