转自:

http://www.cnblogs.com/icerainsoft/p/3584532.html

http://www.cnblogs.com/bingya/articles/3134227.html

在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr() ,这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。

果使用了反向代理软件,将http://192.168.1.110:2046/ 的URL反向代理为http://www.xxx.com/
的URL时,用request.getRemoteAddr() 方法获取的IP地址是:127.0.0.1 或 192.168.1.110
,而并不是客户端的真实IP。
经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接
通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息。用以跟踪原有的客户端IP地址和原来客
户端请求的服务器地址。当我们访问http://www.xxx.com/index.jsp/
时,其实并不是我们浏览器真正访问到了服务器上的index.jsp文件,而是先由代理服务器去访问http://192.168.1.110:2046
/index.jsp
,代理服务器再将访问到的结果返回给我们的浏览器,因为是代理服务器去访问index.jsp的,所以index.jsp中通过
request.getRemoteAddr() 的方法获取的IP实际上是代理服务器的地址,并不是客户端的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.xxx.com/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 getRemoteHost(javax.servlet.http.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.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;
}

如果是Netty4.x

 public String getRemoteIP(FullHttpRequest httpRequest) {
String ip = "";
try{
String ipForwarded = httpRequest.headers().get("x-forwarded-for");
if (StringUtils.isBlank(ipForwarded) || "unknown".equalsIgnoreCase(ipForwarded)) {
InetSocketAddress insocket = (InetSocketAddress)channel.remoteAddress();
ip = insocket.getAddress().getHostAddress();
} else {
ip = ipForwarded;
}
}catch(Exception e){
logger.error("getRemoteIP(): get remote ip fail!", e);
}
if("0:0:0:0:0:0:0:1".equals(ip)){
ip = "127.0.0.1";
}
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

package com.ctrip.cep.mockserver.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest;
import java.io.IOException; /**
* Created by lzyan on 2017/7/11.
*/
public final class NetworkUtil {
private static Logger logger = LoggerFactory.getLogger(NetworkUtil.class); /**
* 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址
*
* @param request
* @return
* @throws IOException
*/
public final static String getIpAddress(HttpServletRequest request) {
// 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址 String ip = request.getHeader("X-Forwarded-For");
// logger.debug("getIpAddress(HttpServletRequest) - X-Forwarded-For - String ip=" + ip); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
// logger.debug("getIpAddress(HttpServletRequest) - Proxy-Client-IP - String ip=" + ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
// logger.debug("getIpAddress(HttpServletRequest) - WL-Proxy-Client-IP - String ip=" + ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
// logger.debug("getIpAddress(HttpServletRequest) - HTTP_CLIENT_IP - String ip=" + ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
// logger.debug("getIpAddress(HttpServletRequest) - HTTP_X_FORWARDED_FOR - String ip=" + ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
// logger.debug("getIpAddress(HttpServletRequest) - getRemoteAddr - String ip=" + ip);
}
} else if (ip.length() > 15) {
String[] ips = ip.split(",");
for (int index = 0; index < ips.length; index++) {
String strIp = ips[index];
if (!("unknown".equalsIgnoreCase(strIp))) {
ip = strIp;
break;
}
}
}
return ip;
} }

根据Request获取客户端IP的更多相关文章

  1. 根据Request获取客户端IP 内网IP及外网IP

    在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr() ,这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实 ...

  2. Request获取客户端IP

    获取客户端的IP地址的方法是:request.getRemoteAddr() ,这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了. ...

  3. C#服务器获取客户端IP地址以及归属地探秘

    背景:博主本是一位Windows桌面应用程序开发工程师,对网络通信一知半解.一日老婆逛完某宝,问:"为什么他们知道我的地址呢,他们是怎么获取我的地址的呢?" 顺着这个问题我们的探秘 ...

  4. JAVA获取客户端IP地址

    在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实I ...

  5. WebService及WCF获取客户端IP,端口

    wcf获取客户端IP,端口 var context = OperationContext.Current; var properties = context.IncomingMessageProper ...

  6. asp.net获取客户端IP方法(转载)

    最近web获取客户端ip,看到下面这篇文章,转载过来,一起分享(转载地址:http://www.cnblogs.com/yejun/archive/2008/02/26/1082485.html) 通 ...

  7. (转)【ASP.NET开发】获取客户端IP地址 via C#

    [ASP.NET开发]获取客户端IP地址 via C# 说明:本文中的内容是我综合博客园上的博文和MSDN讨论区的资料,再通过自己的实际测试而得来,属于自己原创的内容说实话很少,写这一篇是为了记录自己 ...

  8. 获取客户端IP地址 via C#

    获取客户端IP地址 via C# 说明:本文中的内容是我综合博客园上的博文和MSDN讨论区的资料,再通过自己的实际测试而得来,属于自己原创的内容说实话很少,写这一篇是为了记录自己在项目中做过的事情,同 ...

  9. ASP.NET获取客户端信息,获取客户端IP等等

    山上明月 ASP.NET能知道的东西 获取服务器电脑名: Page.Server.ManchineName 获取用户信息: Page.User 获取客户端电脑名:Page.Request.UserHo ...

随机推荐

  1. FTP实验

    一.安装 sudo apt-get install vsftpd service vsftpd start 启动vsftpd服务 如果在不设置任何的情况下,可以以匿名的方式访问该ftp. 这时候你可以 ...

  2. 一键解包/打包boot.img/recovery.img工具(高通/MTK双版 支持android 5.1以上)

    下载地址: 链接: https://pan.baidu.com/s/1hsA2oWc 密码: skdx

  3. Java知多少(48)try语句的嵌套

    Try语句可以被嵌套.也就是说,一个try语句可以在另一个try块内部.每次进入try语句,异常的前后关系都会被推入堆栈.如果一个内部的try语句不含特殊异常的catch处理程序,堆栈将弹出,下一个t ...

  4. Fedora Server 21 安装 搜狗拼音输入法

    最新文章:Virson’s Blog 借鉴文章:博客园-怒杀神殿    ChinaUnix-firo 百度贴吧-fedora吧 方法一:解压deb安装包方式安装: 如果本机已安装ibus,需要先卸载, ...

  5. tmux常用配置

    首先创建配置文件 $ touch ~/.tmux.conf 一,鼠标支持 对于version 2.1 (18 October 2015)之后的版本,编辑配置文件.tmux.conf, 保存即可. se ...

  6. 仿迅雷播放器教程 -- C++ 100款开源界面库 (10)

      (声明:Alberl以后说到开源库,一般都是指著名的.或者不著名但维护至少3年以上的.那些把代码一扔就没下文的,Alberl不称之为开源库,只称为开源代码.这里并不是贬低,像Alberl前面那个系 ...

  7. 解决wireshark检测不到网卡的问题

    第一步 1.打开windows设备管理器. 2.查看-显示隐藏的设备 3.非即插即用驱动程序 4.NetGroup Packet Filter Driver 右键属性---驱动程序---启动类型,修改 ...

  8. 使用 PHP_CodeSniffer 检查 代码 是否 符合 编码规范

    服务端部署:PHP_CodeSniffer HG 服务端部署篇 1.下载PHP_CodeSniffer 前往 https://github.com/squizlabs/PHP_CodeSniffer ...

  9. The last packet successfully received from the server was 20,519 milliseconds ago. The last packet sent successfully to the server was 0 milliseconds ago.

    本地升级了下MySQL的版本,从5.6升为5.7,数据文件直接拷贝的,项目查询数据库报错: Could not retrieve transation read-only status server ...

  10. linux下mysql 文件导入导出

    最近在做mysql的数据导入导出得到的一些经验,记录下. 1.首先要开通导入导出的功能,需要设置一个mysql的配置 可以在 my.conf 文件的最后增加配置项 secure-file-priv=' ...