2013-08-07 19 views
9

Dostaję adres IP poprzez Client poniżej metody:Java - Jak wykryć wersję IP

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

Teraz chcę, aby wykryć, czy jest to IPV4 lub IPV6.

+2

Można użyć wyrażenia regularnego, jak podano tutaj http://www.java2s.com/Code/Java/Network-Protocol/DetermineifthegivenstringisavalidIPv4orIPv6address. htm – Tala

+0

Należy pamiętać, że jeśli X-Forwarded-For nie jest ustawiony przez serwer * twój * (np. BigIP F5), nie można mu ufać, ponieważ może być ustawiony przez klienta na cokolwiek. – lapkritinis

Odpowiedz

15

Można by utworzyć InetAddress i sprawdzić, czy stało się IPv4 lub IPv6 instancja

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

Wydaje się nieco niezręcznie, chociaż, i mam nadzieję, że jest lepszym rozwiązaniem.

+0

Lepiej jak? Opiera się na JDK, a nie na rodzimym regexie. Wydaje mi się OK. – EJP

+2

Lepszy tym, że nie polega na instanceof. Byłoby miło mieć metodę w InetAddress, która zwraca stałą, aby wskazać używaną wersję. – Bex

5

Jeśli masz pewność, że otrzymujesz IPv4 lub IPv6, możesz wypróbować następujące rozwiązania. Jeśli masz nazwę DNS, spróbuje wykonać wyszukiwanie. W każdym razie, spróbuj tego:

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

proszę zmienić "Inet4Address" na "Inet6Address" w części "else". – tokhi

+0

Zrobione, dziękuję za to – morgano

0

Dzięki Tala.

To co próbowałem korzystania z this example z niewielkimi zmianami:

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

Nie używaj w tym celu własnego wyrażenia regularnego. Użyj rozwiązania instanceof. – EJP

+1

Dzięki, yeah 'instanceof' jest bardziej wydajny. – tokhi

+2

Nie mówiłem nic o skuteczności. Jest bardziej * poprawny *, ponieważ jest wbudowany w JDK, a nie jest twoim własnym kodem. – EJP

Powiązane problemy