2013-04-23 37 views
29

Tôi đang gặp một số sự cố với một vấn đề đơn giản. Tôi sẽ nhận được địa chỉ IP thực của trong HTTPServlet.Nhận IP khách hàng thực trong Servlet

Kể từ bây giờ tôi đã sử dụng:

request.getRemoteAddr() 

Nhưng bây giờ nó trả về một IP giả. ví dụ: xxx.xxx.xxx. nhưng IP của tôi giống như xxx.xxx.xxx. . (được kiểm tra tại http://whatismyipaddress.com/).

Bây giờ tôi cố gắng sử dụng:

request.getHeader("X-Forwarded-For") 

Nó trả về NULL.

Tôi cũng đã thăm dò với các lớp sau đây:

public class IpUtils { 

public static final String _255 = "(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"; 
public static final Pattern pattern = Pattern.compile("^(?:" + _255 + "\\.){3}" + _255 + "$"); 

public static String longToIpV4(long longIp) { 
    int octet3 = (int) ((longIp >> 24) % 256); 
    int octet2 = (int) ((longIp >> 16) % 256); 
    int octet1 = (int) ((longIp >> 8) % 256); 
    int octet0 = (int) ((longIp) % 256); 

    return octet3 + "." + octet2 + "." + octet1 + "." + octet0; 
} 

public static long ipV4ToLong(String ip) { 
    String[] octets = ip.split("\\."); 
    return (Long.parseLong(octets[0]) << 24) + (Integer.parseInt(octets[1]) << 16) 
      + (Integer.parseInt(octets[2]) << 8) + Integer.parseInt(octets[3]); 
} 

public static boolean isIPv4Private(String ip) { 
    long longIp = ipV4ToLong(ip); 
    return (longIp >= ipV4ToLong("10.0.0.0") && longIp <= ipV4ToLong("10.255.255.255")) 
      || (longIp >= ipV4ToLong("172.16.0.0") && longIp <= ipV4ToLong("172.31.255.255")) 
      || longIp >= ipV4ToLong("192.168.0.0") && longIp <= ipV4ToLong("192.168.255.255"); 
} 

public static boolean isIPv4Valid(String ip) { 
    return pattern.matcher(ip).matches(); 
} 

public static String getIpFromRequest(HttpServletRequest request) { 
    String ip; 
    boolean found = false; 
    if ((ip = request.getHeader("x-forwarded-for")) != null) { 
     StringTokenizer tokenizer = new StringTokenizer(ip, ","); 
     while (tokenizer.hasMoreTokens()) { 
      ip = tokenizer.nextToken().trim(); 
      if (isIPv4Valid(ip) && !isIPv4Private(ip)) { 
       found = true; 
       break; 
      } 
     } 
    } 

    if (!found) { 
     ip = request.getRemoteAddr(); 
    } 

    return ip; 
} 
} 

Nó cũng trả lại xxx.xxx.xxx.50 IP. :(

Bây giờ tôi không biết làm thế nào để có được địa chỉ IP của khách hàng thực sự. Nếu ai đó biết giải pháp xin vui lòng thực hiện một câu trả lời.

+0

là máy chủ của bạn kết nối trực tiếp với internet? Có bất kỳ bộ định tuyến, cân bằng tải, thiết bị NAT, vv? – mindas

+0

Chỉ có một ruter. – TAR515

Trả lời

27

Tôi cho rằng sự cố của bạn là bạn đang chạy máy chủ ở đâu đó trong mạng cục bộ, do đó bạn có được IP của mình trong mạng đó. Tuy nhiên khi bạn đang cố gắng sử dụng dịch vụ trực tuyến phát hiện ra địa chỉ IP của bạn, IP của bạn là IP của bộ định tuyến của nhà cung cấp dịch vụ của bạn hoặc một cái gì đó như thế này. Sử dụng request.getRemoteAddr() là chính xác. Đây là những dịch vụ như vậy và họ không có các phương tiện khác.

+0

Máy chủ của tôi (với servlet) và máy khách của tôi chạy cùng một máy tính. Nhưng tôi không nhận được localhost như IP vì client sử dụng IP thực khi nó kết nối với máy chủ. 188.xxx.xxx.158. Tôi đã sử dụng nó từ bây giờ và nó hoạt động hoàn hảo, đây là lần đầu tiên tôi nhận được một IP giả. – TAR515

12

Khi bạn có NAT (Network Address Translation) thiết bị trước khi servlet container của bạn request.getRemoteAddr() trả về địa chỉ của NAT, vì nó bắt đầu một kết nối mới

Để giải quyết vấn đề của bạn, bạn nên định cấu hình NAT để gửi tiêu đề IP của ứng dụng khách ban đầu Sau đó, để lấy tiêu đề từ yêu cầu. trường hợp bạn định cấu hình trong tiêu đề NAT X-Forwarded-For sử dụng mã này: request.getHeader("X-Forwarded-For")

Chức năng của bạn là chính xác, bạn có thể sử dụng nó khi bạn định cấu hình NAT.

+0

Tôi không sử dụng bất kỳ thiết bị NAT nào, như tôi biết :) – TAR515

8

Java

String ip = request.getRemoteAddr(); 
if (ip.equalsIgnoreCase("0:0:0:0:0:0:0:1")) { 
    InetAddress inetAddress = InetAddress.getLocalHost(); 
    String ipAddress = inetAddress.getHostAddress(); 
    ip = ipAddress; 
} 
model.addAttribute("IP", ip); 

JSP <span><B>IP : <c:out value="${IP}" /></B></span> // Spring MAV 

JSP

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> 
<%@ page import="java.net.InetAddress" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 
<title>Displays Client IP Address</title> 
</head> 
<body> 
<% 
    // paste above java code 
out.println("<br><B>Clients IP : </B>"+ip); 
%> 
<span><br>Local Host : <%= request.getRemoteAddr() %></span> 
<span><br>ServerPort : <%= request.getServerPort() %></span> 
<span><br>Path  : <%= request.getRequestURI()%></span> 
</span> 
</body> 
</html> 

Nếu jsp được triển khai trong máy chủ cục bộ và truy cập jsp này trả về 0: 0: 0: 0: 0: 0: 0 : 1. Nếu truy cập ứng dụng cục bộ bằng ip thì nó sẽ trả về IP.

RESTful Web Services với Jersey

@javax.ws.rs.Path("/ip") 
public class GetIPInfo { 

    @GET @Produces(MediaType.TEXT_PLAIN) 
    public Response getIP(@Context javax.servlet.http.HttpServletRequest request) throws UnknownHostException { 

     String remoteHost = request.getRemoteHost(); 
     String remoteAddr = request.getRemoteAddr(); 
     if (remoteAddr.equals("0:0:0:0:0:0:0:1")) { 
      InetAddress localip = java.net.InetAddress.getLocalHost(); 
      remoteAddr = localip.getHostAddress(); 
      remoteHost = localip.getHostName(); 
     } 
     int remotePort = request.getRemotePort(); 

     String msgoutput = remoteHost + " (" + remoteAddr + " : " + remotePort + ")"; 
     return Response.status(200).entity(msgoutput).build(); 
    } 
} 

sử dụng JavaScript để tìmIP

Các vấn đề liên quan