2013-08-07 39 views
9

tôi nhận được địa chỉ IP Client qua dưới phương pháp:Java - Làm thế nào để phát hiện phiên bản IP

public static String getClientIpAddr(HttpServletRequest request) { 
    String ip = request.getHeader("X-Forwarded-For"); 
    ... 
    return ip 
} 

Bây giờ tôi muốn để phát hiện nếu nó là một IPV4 hoặc một IPV6.

+2

Bạn có thể sử dụng regex như đã nêu ở đây http://www.java2s.com/Code/Java/Network-Protocol/DetermineifthegivenstringisavalidIPv4orIPv6address. htm – Tala

+0

Hãy lưu ý rằng trừ khi X-Forwarded-For được thiết lập bởi một số * máy chủ * của bạn (Giống như BigIP F5), nó không thể tin cậy vì nó có thể được thiết lập bởi máy khách đến bất cứ thứ gì. – lapkritinis

Trả lời

15

Bạn có thể tạo một InetAddress và kiểm tra xem nó đã trở thành một ipv4 hoặc dụ ipv6

InetAddress address = InetAddress.getByName(ip); 
if (address instanceof Inet6Address) { 
    // It's ipv6 
} else if (address instanceof Inet4Address) { 
    // It's ipv4 
} 

Nó có vẻ hơi lúng túng, mặc dù, và tôi hy vọng có một giải pháp tốt hơn.

+0

Tốt hơn như thế nào? Nó dựa trên JDK chứ không phải là một regex nhà trồng. Có vẻ ổn với tôi. – EJP

+2

Tốt hơn ở chỗ nó không dựa trên instanceof. Nó sẽ là tốt đẹp để có một phương pháp trong InetAddress trả về một hằng số để cho biết phiên bản đang được sử dụng. – Bex

5

Nếu bạn chắc chắn mình đang sử dụng IPv4 hoặc IPv6, bạn có thể thử các bước sau. Nếu bạn có một tên DNS thì điều này sẽ cố gắng thực hiện một tra cứu. Dù sao, hãy thử cách này:

try { 

    InetAddress address = InetAddress.getByName(myIpAddr); 

    if (address instanceof Inet4Address) { 
     // your IP is IPv4 
    } else if (address instanceof Inet6Address) { 
     // your IP is IPv6 
    } 

} catch(UnknownHostException e) { 

    // your address was a machine name like a DNS name, and couldn't be found 

} 
+0

hãy thay đổi 'Inet4Address' thành' Inet6Address' trong phần 'else'. – tokhi

+0

Xong, cảm ơn vì điều đó – morgano

0

Nhờ Tala.

Đây là những gì tôi đã cố gắng sử dụng các this example với những thay đổi nhỏ:

private static Pattern VALID_IPV4_PATTERN = null; 
    private static Pattern VALID_IPV6_PATTERN = null; 
    private static final String ipv4Pattern = "(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])"; 
    private static final String ipv6Pattern = "([0-9a-f]{1,4}:){7}([0-9a-f]){1,4}"; 

    static { 
    try { 
     VALID_IPV4_PATTERN = Pattern.compile(ipv4Pattern, Pattern.CASE_INSENSITIVE); 
     VALID_IPV6_PATTERN = Pattern.compile(ipv6Pattern, Pattern.CASE_INSENSITIVE); 
    } catch (PatternSyntaxException e) { 
     //logger.severe("Unable to compile pattern", e); 
    } 
    } 

    public static String isIpAddressV4orV6(String ipAddress) { 

     Matcher ipv4 = IP_Utilities.VALID_IPV4_PATTERN.matcher(ipAddress); 
     if (ipv4.matches()) { 
      return "IPV4"; 
     } 
     Matcher ipv6 = IP_Utilities.VALID_IPV6_PATTERN.matcher(ipAddress); 
     if (ipv6.matches()) { 
       return "IPV6"; 
     } 
     return ""; 
    } 
+0

Không sử dụng regex của riêng bạn cho việc này. Sử dụng giải pháp instanceof. – EJP

+1

Cảm ơn, vâng 'instanceof' hiệu quả hơn. – tokhi

+2

Tôi không nói gì về hiệu quả. Nó chính xác hơn * bởi vì nó được xây dựng trong JDK như trái ngược với mã của riêng bạn. – EJP

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