根据Request获取客户端IP 内网IP及外网IP
在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地址的方法一:
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
/**
* The Class IpUtils.
*
*/
public abstract class IpUtils {
/**
* Gets the client ip addr.
*
* @param request the request
* @return the client ip addr
*/
public static String getClientIpAddr(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;
}
/**
* Gets the real ips.
*
* @return the real ips
*/
public static List<String> getRealIps() {
List<String> ips = new ArrayList<String>();
String localip = null;// 本地IP,如果没有配置外网IP则返回它
String netip = null;// 外网IP
Enumeration<NetworkInterface> netInterfaces;
try {
netInterfaces = NetworkInterface.getNetworkInterfaces();
} catch (SocketException e) {
return null;
}
InetAddress ip = null;
boolean finded = false;// 是否找到外网IP
while (netInterfaces.hasMoreElements() && !finded) {
NetworkInterface ni = netInterfaces.nextElement();
Enumeration<InetAddress> address = ni.getInetAddresses();
while (address.hasMoreElements()) {
ip = address.nextElement();
if (!ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {// 外网IP
netip = ip.getHostAddress();
ips.add(netip);
finded = true;
break;
} else if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {// 内网IP
localip = ip.getHostAddress();
ips.add(localip);
}
}
}
return ips;
}
/**
* Gets the real ip.
*
* @return the real ip
*/
public static String getRealIp() {
return getRealIps().iterator().next();
}
}
根据Request获取客户端IP 内网IP及外网IP的更多相关文章
- iptables 实现centos内网机器访问外网
环境:一台带外网和内网的机器,另一台只有内网,默认不能上网.两台机器都是centos系统带外网机器的外网ip为 123.221.20.11, 内网ip为 192.168.15.100内网机器的内网ip ...
- openvpn实现内网 映射到 外网
openvpn实现内网 映射到 外网 场景介绍: 机器介绍 本地一台Ubuntu服务器A , 处于内网中 , 无外网IP 外网一台Ubuntu服务器B , 外网地址139.199.4.205 目标 : ...
- Request获取客户端IP
获取客户端的IP地址的方法是:request.getRemoteAddr() ,这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了. ...
- 根据Request获取客户端IP
转自: http://www.cnblogs.com/icerainsoft/p/3584532.html http://www.cnblogs.com/bingya/articles/3134227 ...
- 【C#】C#获取本地的内网(局域网)和外网(公网)IP地址的方法
1.获取本机的IP地址集合: /// <summary> /// 获取本机所有ip地址 /// </summary> /// <param name="netT ...
- 通过Request获取客户端的真实IP
我们在做项目的时候经常需要获取客户端的真实ip去进行判断,为此搜索了相关文章,以下这个讲解的比较明白,直接拿来 https://blog.csdn.net/yin_jw/article/details ...
- .NET 获取客户端的操作系统版本、浏览器版本和IP地址
我们在使用.NET做网站的时候,很多情况下需要需要知道客户端的操作系统版本和浏览器版本,怎样获取客户端的操作系统和浏览器版本呢?我们可以通过分析UserAgent来获取. .NET 获取客户端的操作系 ...
- dubbo调用外网接口 注册外网ip到zookeeper 暴露外网ip
dubbo注册时会通过主机名寻找ip,会将内网ip注册到zookeeper 如果我们调用外网服务器server的话是找不到的 会报如下错误 [DUBBO] client reconnect to 12 ...
- frp内网 穿透映射使内网svn可外网访问
起因 公司svn目前部署在内网服务器上,现在想在家中也可以使用,因此需要外网访问内网的工具 经过 使用过几个产品: utools,一个小巧的windows下的工具,内网映射只是它的一个小功能,支持tc ...
随机推荐
- PHP的几个常用函数的使用总结
1.date函数:不得不说,PHP的date函数已经基本很完备了,如果你不去读PHP的手册的话,你不会发现对日期做了那么多的支持. time() 获取当前的时间戳 data() 获取自己想要的时间格 ...
- Linux Shell 2>&1 &
转 脚本如: nohup /mnt/Nand3/H2000G >/dev/null 2>&1 & 对 于& 1 更准确的说应该是文件描述符 1,而1 一般代表的就 ...
- 最大流模版 pascal
//最大流模版 ; maxm=; ..maxn] of integer; end; var n,m,max:longint; r:..maxn,..maxn] of longint; g:..maxn ...
- angular 滚动
AngularJs $anchorScroll.$controller.$document $anchorScroll 根据HTML5的规则,当调用这个函数时,它检查当前的url的hash值并且滚动到 ...
- Ansible-Tower快速入门-7.配置实时事件【翻译】
配置实时事件 在tower的菜单中,在接近用户菜单处有一个带有颜色的小点,这个带颜色的小点显示tower的实时事件功能的状态 如果这个小点是绿色的,表示运行正常,如果这个小点是红色或橙色,表示实时事件 ...
- MVC 知识点学习1
1.@Scripts.Render("~/bundles/kindeditor");@Styles.Render("~/Css/") //(加载)引用bun ...
- libev学习(一)
一.libev简介 Libev是一个事件循环:你注册感兴趣的特定事件(比如一个文件可以读取时或者发生超时时),它将管理这些事件源,将这些事件反馈给你的程序.为了实现这些,至少要在你的进程(或线程)中执 ...
- PHP explode()函数
源起:将日期格式的字符串拆分成年.月.日,用于组织关系介绍信的特定位置打印.感谢倪同学提供思路 定义和用法 explode()函数把字符串分割为数组 语法 explode(separator,stri ...
- Launching the Debugger Automatically
You can set up your application to start Visual Studio when you launch the application from Windows. ...
- CSharper~
昨天晚上开始,重启读clr via c#大计.Jeffery大神的大作基本上没人不推荐的,所以我也抱了很大的期待,希望读完以后对.net的认识能有质的飞跃.争取五月份内读完.昨天看完了第一章,感觉.n ...