获取B/S客户端IP

   最近想写个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  

你可能感兴趣的:(java,编程,jsp,Web,浏览器)