获取B/S客户端IP

来源:互联网 发布:网络在线对外汉语教师 编辑:程序博客网 时间:2024/05/16 19:43


java浏览器Web编程JSP
   最近想写个B/S架构的聊天系统,因为以前做过C/S架构的QQ聊天系统,所以对于Socket通信编程只是一个巩固。对于C/S架构的聊天系统,由于存在客户端Java应用,所以直接在代码中获取客户端的IP,应用的方法为: 
   String ip = InetAddress.getLocalHost().getHostAddress(); 
然而对于WEB系统来说,客户端只是一个浏览器,怎么才能获取用户的IP呢,而且又要分内网环境和外网环境两种。 
  内网环境: 
      聊天系统用于内网的话,我首先想到了通过JS来实现获取用户的IP,确实也有方法可以支持: 
       //通过js获得客户端IP,这里获取的IP是本机所有的IP(包括内网和外网) 
function GetLocalIPAddr(){ 
var oSetting = null; 
var ip = null; 
try{ 
      oSetting = new ActiveXObject("rcbdyctl.Setting"); 
      ip = oSetting.GetIPAddress; 
      if (ip.length == 0){ 
  return "没有连接到Internet"; 
      } 
oSetting = null; 
      }catch(e){ 
   return ip; 
      } 
return ip; 

     不过此方法只支持IE浏览器,我不得不加了个判断浏览器类别的方法: 
//首先判断客户端的浏览器情况 
   $(function(){ 
        if($.browser.msie){ 
           clientIP =  GetLocalIPAddr(); 
           $("#showMessage").html("您的IP为:"+dealWith(clientIP)); 
           sendMessageToServlet("busi=connect&connectIP="+dealWith(clientIP)); 
        }else if($.browser.opera){ 
            //alert("这是一个opera浏览器!"); 
            $("#showMessage").html("建议您使用IE浏览器,否则要手动输入IP!"); 
        }else if($.browser.mozilla){ 
            //alert("这是一个mozilla浏览器!"); 
            $("#showMessage").html("建议您使用IE浏览器,否则要手动输入IP!"); 
        }else if($.browser.safa){ 
            //alert("这是一个safa浏览器!"); 
            $("#showMessage").html("建议您使用IE浏览器,否则要手动输入IP!"); 
        } 
   }); 
        怎么才能完整的获取客户端的IP呢?(如果有哪位朋友做过,期望指点一下啊,交个朋友,呵呵) 
  外网环境: 
       我们这边在做的网上营业厅系统中有获取用户外网IP的方法,实现方法: 
public static String getCurrentIP(HttpServletRequest request){ 
String result = ""; 
if (result == null || result.length() == 0 
|| "unknown".equalsIgnoreCase(result)) { 
result = request.getHeader("x-forwarded-for"); 

if (result == null || result.length() == 0 
|| "unknown".equalsIgnoreCase(result)) { 
result = request.getHeader("X-Forwarded-For"); 

if (result == null || result.length() == 0 
|| "unknown".equalsIgnoreCase(result)) { 
result = request.getHeader("Proxy-Client-IP"); 

if (result == null || result.length() == 0 
|| "unknown".equalsIgnoreCase(result)) { 
result = request.getHeader("WL-Proxy-Client-IP"); 

if (result == null || result.length() == 0 
|| "unknown".equalsIgnoreCase(result)) { 
result = request.getHeader("HTTP_X_FORWARDED_FOR"); 

if (!StringUtils.isEmpty(result)) { 
if (result.indexOf(".") != -1){ // 没有"."肯定是非IPv4格式 
Pattern pat = Pattern.compile("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"); 
Matcher mat = pat.matcher(result); 
result = null; 
while (mat.find()) { 
result = mat.group(0); 
break; 


else 
result = null; 


下面是网上广为流传的解释: 
在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。   
    如果使用了反向代理软件,将http://192.168.1.110 :2046/ 的URL反向代理为 http://www.xxx.cn / 的URL时,用request.getRemoteAddr()方法获取的IP地址是:127.0.0.1 或 192.168.1.110,而并不是客户端的真实IP。  
    经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器 无法直接拿到客户端的IP,服务器 端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息。用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。当我们访问http://www.5555.cn /index.jsp/ 时,其实并不是我们浏览器真正访问到了服务器上的index.jsp文件,而是先由代理服务器去访问http://192.168.1.110 :2046/index.jsp ,代理服务器再将访问到的结果返回给我们的浏览器,因为是代理服务器去访问index.jsp的,所以index.jsp中通过 request.getRemoteAddr()的方法获取的IP实际上是代理服务器的地址,并不是客户端的IP地址。   
public String getRemortIP(HttpServletRequest request) {  
  if (request.getHeader("x-forwarded-for") == null) {  
   return request.getRemoteAddr();  
  }  
  return request.getHeader("x-forwarded-for");  
}   
  
    可是当我访问http://www.5555.cn /index.jsp/ 时,返回的IP地址始终是unknown,也并不是如上所示的127.0.0.1 或 192.168.1.110了,而我访问http://192.168.1.110 :2046/index.jsp 时,则能返回客户端的真实IP地址,写了个方法去验证。原因出在了Squid上。squid.conf 的配制文件 forwarded_for 项默认是为on,如果 forwarded_for 设成了 off  则:X-Forwarded-For: unknown   
    于是可得出获得客户端真实IP地址的方法二:   
  
public String getIpAddr(HttpServletRequest request) {     
       String ip = request.getHeader("x-forwarded-for");     
       if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {     
           ip = request.getHeader("Proxy-Client-IP");     
       }     
       if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {     
           ip = request.getHeader("WL-Proxy-Client-IP");     
       }     
       if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {     
           ip = request.getRemoteAddr();     
       }     
       return ip;     
   }     
  
public String getIpAddr(HttpServletRequest request) {  
       String ip = request.getHeader("x-forwarded-for");  
       if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
           ip = request.getHeader("Proxy-Client-IP");  
       }  
       if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
           ip = request.getHeader("WL-Proxy-Client-IP");  
       }  
       if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
           ip = request.getRemoteAddr();  
       }  
       return ip;  
   }   
  
  
    可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串Ip值,究竟哪个才是真正的用户端的真实IP呢?   
    答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。   
    如:X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100用户真实IP为: 192.168.1.110  
原创粉丝点击