网站模板套用,大方网站制作,做一个安卓app多少钱,站长之家网页模板真正的取真实IP地址及利弊(转自百度空间)目前网上流行的所谓“取真实IP地址”的方法#xff0c;都有bug#xff0c;没有考虑到多层透明代理的情况。 多数代码类似#xff1a; string IpAddress (HttpContext.Current.Request.ServerVariables[HTTP_X_FORWARDED_FOR都有bug没有考虑到多层透明代理的情况。 多数代码类似 string IpAddress (HttpContext.Current.Request.ServerVariables[HTTP_X_FORWARDED_FOR]!null HttpContext.Current.Request.ServerVariables[HTTP_X_FORWARDED_FOR] !String.Empty) ?HttpContext.Current.Request.ServerVariables[HTTP_X_FORWARDED_FOR] :HttpContext.Current.Request.ServerVariables[REMOTE_ADDR]; 事实上上面的代码只试用与用户只使用了1层代理如果用户有2层3层HTTP_X_FORWARDED_FOR 的值是“本机真实IP,1层代理IP,2层代理IP,.....” 如果这个时候你的数据中保存IP字段的长度很小15个字节数据库就报错了。 实际应用中因为使用多层透明代理的情况比较少所以这种用户并不多。 其他应用情况现在越来越多的网站使用了代理加速方式比如 新浪、SOHU的新闻 都使用Squid做代理方式利用多台服务器分流。Squid本身类似透明代理会发送“HTTP_X_FORWARDED_FOR” HTTP_X_FORWARDED_FOR 中包括客户的IP地址如果此时客户已经使用了一层透明代理那么程序取的 “HTTP_X_FORWARDED_FOR” 就包括两个IP地址。我遇到过3个IP地址的情况4个的未遇到过 所以取“真正”IP地址的方式还应该判断 “HTTP_X_FORWARDED_FOR” 中是否有“,”逗号或者长度是否超长超过15字节 xxx.xxx.xxx.xxx。 所以代码应该如下 /** summary /// 取得客户端真实IP。如果有代理则取第一个非内网地址 /// /summary public static string IPAddress { get { string result String.Empty; result HttpContext.Current.Request.ServerVariables[HTTP_X_FORWARDED_FOR]; if(result!nullresult! String.Empty) { //可能有代理 if(result.IndexOf(.)-1) //没有“.”肯定是非IPv4格式 result null; else { if(result.IndexOf(,)!-1) { //有“,”估计多个代理。取第一个不是内网的IP。 result result.Replace( ,).Replace(,); string[] temparyip result.Split(,;.ToCharArray()); for(int i0;itemparyip.Length;i) { if( Text.IsIPAddress(temparyip[i]) temparyip[i].Substring(0,3)!10. temparyip[i].Substring(0,7)!192.168 temparyip[i].Substring(0,7)!172.16.) { return temparyip[i]; //找到不是内网的地址 } } } else if(Text.IsIPAddress(result)) //代理即是IP格式 return result; else result null; //代理中的内容 非IP取IP } } string IpAddress (HttpContext.Current.Request.ServerVariables[HTTP_X_FORWARDED_FOR]!null HttpContext.Current.Request.ServerVariables[HTTP_X_FORWARDED_FOR] !String.Empty)?HttpContext.Current.Request.ServerVariables[HTTP_X_FORWARDED_FOR]:HttpContext.Current.Request.ServerVariables[REMOTE_ADDR]; if (null result || result String.Empty) result HttpContext.Current.Request.ServerVariables[REMOTE_ADDR]; if (result null || result String.Empty) result HttpContext.Current.Request.UserHostAddress; return result; } } 取“HTTP_X_FORWARDED_FOR” 的弊端。 HTTP_X_FORWARDED_FOR 是HTTP协议中头的一部分不影响TCP的通讯。也就是说实际上客户端可以发送任意内容的 HTTP_X_FORWARDED_FOR以就是伪造IP。最简单的是WEB程序的IP记录本来是要记录真实IP的反而被“黑客”欺骗。当你的应用程序记录客户的访问IP、拒绝或允许部分IP的访问、错误日志 都会出错甚至误杀。 因此必要的安全日志应该记录 完整的 “HTTP_X_FORWARDED_FOR” 至少给数据库中的字段分配 3*152 个字节以记录至少3个IP 和 “REMOTE_ADDR”。对 HTTP_X_FORWARDED_FOR 的IP格式检查也是不可少的。附:(Text是我自定义的一个类IsIPAddress是其中的一个判断是否是IP地址格式的方法) #region bool IsIPAddress(str1) 判断是否是IP格式 /** summary /// 判断是否是IP地址格式 0.0.0.0 /// /summary /// param namestr1待判断的IP地址/param /// returnstrue or false/returns public static bool IsIPAddress(string str1) { if(str1null||str1string.Empty||str1.Length7||str1.Length15) return false; string regformat ^\d{1,3}[\.]\d{1,3}[\.]\d{1,3}[\.]\d{1,3}$; Regex regex new Regex(regformat,RegexOptions.IgnoreCase ); return regex.IsMatch(str1); } #endregion 原文地址http://blog.csdn.net/kingwkb/archive/2006/04/05/651127.aspx 获取客户端IP:private string GetClientIP() { string result HttpContext.Current.Request.ServerVariables[HTTP_X_FORWARDED_FOR]; if (null result || result String.Empty) { result HttpContext.Current.Request.ServerVariables[REMOTE_ADDR]; } if (null result || result String.Empty) { result HttpContext.Current.Request.UserHostAddress; } return result; }获取MAC地址:[DllImport(Iphlpapi.dll)] private static extern int SendARP(Int32 dest,Int32 host,ref Int64 mac,ref Int32 length); [DllImport(Ws2_32.dll)] private static extern Int32 inet_addr(string ip); private void Page_Load(object sender, System.EventArgs e) { // 在此处放置用户代码以初始化页面 try { string useripRequest.UserHostAddress; string strClientIP Request.UserHostAddress.ToString().Trim(); Int32 ldest inet_addr(strClientIP); //目的地的ip Int32 lhost inet_addr(); //本地服务器的ip Int64 macinfo new Int64(); Int32 len 6; int res SendARP(ldest,0, ref macinfo, ref len); string mac_srcmacinfo.ToString(X); if(mac_src 0) { if(userip127.0.0.1) Response.Write (正在访问Localhost!); else Response.Write (欢迎来自IP为 userip 的朋友 br); return; } while(mac_src.Length12) { mac_src mac_src.Insert(0,0); } string mac_dest; for(int i0;i11;i) { if (0 (i % 2)) { if ( i 10 ) { mac_dest mac_dest.Insert(0,mac_src.Substring(i,2)); } else { mac_dest - mac_dest.Insert(0,mac_src.Substring(i,2)); } } } Response.Write (欢迎来自IP为userip br ,MAC地址为mac_dest的朋友 br); } catch(Exception err) { Response.Write(err.Message); } } 在ASP中使用 Request.ServerVariables(REMOTE_ADDR) 来取得客户端的IP地址但如果客户端是使用代理服务器来访问那取到的就是代理服务器的IP地址而不是真正的客户端IP地址。要想透过代理服务器取得客户端的真实IP地址就要使用 Request.ServerVariables(HTTP_X_FORWARDED_FOR) 来读取。不过要注意的事并不是每个代理服务器都能用 Request.ServerVariables(HTTP_X_FORWARDED_FOR) 来读取客户端的真实 IP有些用此方法读取到的仍然是代理服务器的IP。还有一点需要注意的是如果客户端没有通过代理服务器来访问那么用 Request.ServerVariables (HTTP_X_FORWARDED_FOR) 取到的值将是空的。因此如果要在程序中使用此方法可以这样处理 ...... userip Request.ServerVariables(HTTP_X_FORWARDED_FOR) If userip Then userip Request.ServerVariables(REMOTE_ADDR) ...... 即如果客户端通过代理服务器则取 HTTP_X_FORWARDED_FOR 的值如果没通过代理服务器就取 REMOTE_ADDR 的值。 以下是引用片段 % 通用函数如果不能取客户端真实IP就会取客户端的代理IP Private Function getIP() Dim strIPAddr If Request.ServerVariables(HTTP_X_FORWARDED_FOR) OR InStr(Request.ServerVariables(HTTP_X_FORWARDED_FOR), unknown) 0 Then strIPAddr Request.ServerVariables(REMOTE_ADDR) ElseIf InStr(Request.ServerVariables(HTTP_X_FORWARDED_FOR), ,) 0 Then strIPAddr Mid(Request.ServerVariables(HTTP_X_FORWARDED_FOR), 1, InStr(Request.ServerVariables(HTTP_X_FORWARDED_FOR), ,)-1) ElseIf InStr(Request.ServerVariables(HTTP_X_FORWARDED_FOR), ;) 0 Then strIPAddr Mid(Request.ServerVariables(HTTP_X_FORWARDED_FOR), 1, InStr(Request.ServerVariables(HTTP_X_FORWARDED_FOR), ;)-1) Else strIPAddr Request.ServerVariables(HTTP_X_FORWARDED_FOR) End If getIP Trim(Mid(strIPAddr, 1, 30)) End Function response.write getip() %转载于:https://www.cnblogs.com/zhanghonjiang2011/archive/2012/04/13/2445673.html