在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。
如果使用了反向代理软件,将http://192.168.1.110:2046/ 的URL反向代理为 http://www.javapeixun.com.cn / 的URL时,用request.getRemoteAddr()方法获取的IP地址是:127.0.0.1 或 192.168.1.110,而并不是客户端的真实IP。
经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息。用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。当我们访问http://www.javapeixun.com.cn /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.5a520.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;
}
可是,如果通过了多级反向代理的话,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获取客户端真实IP的两种方法详解 #### 一、问题背景 在Web开发中,经常需要获取客户端的真实IP地址来进行一系列的操作,比如统计访问来源、进行地理定位、安全防护等。然而,在实际应用场景中,客户端请求...
Java的`FTPClient`提供了`enterLocalPassiveMode()`和`enterLocalActiveMode()`切换这两种模式。 8. **断开连接**:完成文件传输后,应使用`disconnect()`方法断开与服务器的连接,释放资源。 9. **错误处理**:在...
Java FTP客户端需要能够处理这两种模式。 Java中的`java.io`和`java.nio`包提供了用于处理输入输出流的类,如`BufferedReader`、`BufferedWriter`、`DataInputStream`和`DataOutputStream`,它们是实现FTP协议基础...
IP地址是互联网上设备的唯一标识,分为IPv4和IPv6两种类型。同样,我们可以使用`InetAddress`类来获取: ```java import java.net.InetAddress; import java.net.UnknownHostException; public class NetDemo_1 { ...
下面是获取客户端真实IP地址的两种方法: 方法一: ```java public String getRemortIP(HttpServletRequest request) { if (request.getHeader("x-forwarded-for") == null) { return request.getRemoteAddr(); ...
有两种方式可以获取客户端真实IP地址,一种是直接访问服务器端,另一种是通过多级代理最终到达服务器端。 对于直接访问服务器端的方式,可以通过getRemoteAddr()方法获得客户端真实IP地址。然而,对于通过多级代理...
本文将深入探讨Java客户端和服务器端之间的通信机制,这对于初学者来说是非常重要的基础知识。 首先,我们要理解“客户端”和“服务器端”的概念。在客户端-服务器模型中,客户端是发起请求的一方,而服务器端则是...
`request.getRemoteAddr()`是一个常用的Java方法,用于获取客户端的IP地址。这个方法在没有使用代理服务器的情况下非常有效。但在使用了Apache、Squid等反向代理软件的情况下,此方法将不再适用,因为它只能获取到...
FTP有主动和被动两种模式,主动模式由客户端打开一个数据连接到服务器,而在被动模式中,服务器会打开一个端口等待客户端连接。 在Java中,`org.apache.commons.net.ftp`库提供了FTPClient类,它简化了与FTP服务器...
Java的`org.apache.commons.net.ftp.FTPClient`库提供了这两种模式的支持。 4. **文件传输**:Java FTP客户端支持ASCII和二进制模式的文件传输。ASCII模式适用于文本文件,而二进制模式适用于所有其他类型的文件,...
Socket提供了一种在两个网络连接点之间建立连接的方法,使得数据可以在客户端和服务器之间双向传输。 1. **Java客户端**:在Eclipse中创建Java客户端程序,我们需要导入`java.net.Socket`库。客户端首先创建一个...
FTP有两种工作模式:主动模式和被动模式。主动模式中,客户端打开一个数据连接到服务器;被动模式下,服务器打开一个数据连接到客户端,以绕过某些防火墙或NAT设备的问题。 2. **Java Socket编程**: 使用`java...
以下是两种常见的Java方法来获取客户端真实IP: **方法一:** ```java public String getRemortIP(HttpServletRequest request) { if (request.getHeader("x-forwarded-for") == null) { return request....
它分为两种工作模式:主动模式(Active Mode)和被动模式(Passive Mode)。主动模式中,服务器主动连接客户端的某个端口,而被动模式则由客户端发起连接,适用于防火墙和NAT环境。 二、Java中的FTP支持 Java提供了...
Java Socket是Java编程语言中用于实现网络通信的一种基础工具,它允许两个应用程序通过TCP/IP协议进行数据交换。在这个"java socket 客户端和服务端例子"中,我们有两个主要组件:服务端(server)和客户端(client...
同时,由于涉及到跨平台通信,对Java和C#两种语言的特性、API以及异常处理机制的熟悉也是必不可少的。 总的来说,Netty和DotNetty的结合使用为Java和C#之间提供了高效、可靠的网络通信方案。开发者需要掌握相关的...
Socket通讯是一种基于网络协议(如TCP/IP)进行进程间通信的技术,它允许不同计算机上的应用程序通过网络进行数据交换。在本场景中,我们探讨的是如何使用`.NET`作为服务器端,`Java`作为客户端实现这样的通信。 ...
在这个“Java客户端服务器程序学习笔记”中,我们将深入探讨这一主题,包括如何设计、实现和交互这两个关键组件。 首先,客户端是用户与系统进行交互的部分,它发送请求到服务器并接收响应。服务器端则处理这些请求...
首先,OPC UA 包含了客户端和服务端两部分,客户端用于请求和访问服务器上的数据,而服务端则提供数据和服务。在Java中,我们可以使用开源库如OpenOPC或 OPC-UA-Stack 来实现 OPC UA 的功能。 1. **客户端实现**: ...
在这个Java实现的UDP简易客户端与服务器端程序中,我们可以通过两个核心文件——UDPClient.java和UDPServer.java来理解其工作原理。 首先,让我们来看看`UDPServer.java`。服务器端通常负责监听特定的端口,接收...