2013-08-07 84 views
9

我通過以下方式獲得Client IP地址:爪哇 - 如何檢測IP版本

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

現在我要來檢測,如果它是一個IPV4IPV6

+2

您可以使用正則表達式如下http://www.java2s.com/Code/Java/Network-Protocol/Det​​ermineifthegivenstringisavalidIPv4orIPv6address說。 htm – Tala

+0

請注意,除非X-Forwarded-For由* your * server的某些設置(如BigIP F5),否則它不能被信任,因爲它可以由客戶端設置爲任何東西。 – lapkritinis

回答

15

您可以創建一個InetAddress和檢查,如果它成爲一個IPv4或IPv6例如

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

這似乎有點尷尬,不過,我希望有一個更好的解決方案。

+0

更好?它依賴於JDK而不是本土的正則表達式。對我來說似乎很好。 – EJP

+2

更好的是它不依賴於instanceof。在InetAddress中有一個方法會很好,它會返回一個常量來指示正在使用的版本。 – Bex

5

如果您確定要獲得IPv4或IPv6,可以嘗試以下操作。如果你有一個DNS名稱,那麼這將嘗試執行查找。無論如何,試試這個:

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

請在'else'部分將'Inet4Address'改爲'Inet6Address'。 – tokhi

+0

完成,謝謝你 – morgano

0

感謝Tala

這是我一直在使用的this example有細微的變化的嘗試:

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

不要使用你自己的正則表達式。使用instanceof解決方案。 – EJP

+1

謝謝,是''instanceof'更高效。 – tokhi

+2

我沒有對效率做任何說明。它更正確*因爲它內置於JDK而不是您自己的代碼。 – EJP