2013-08-07 12 views
9

sto ottenendo l'indirizzo IP Client via di seguito il metodo:Java - Come rilevare la versione IP

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

Ora voglio rilevare se si tratta di un IPV4 o un IPV6.

+2

È possibile utilizzare espressioni regolari, come indicato qui http://www.java2s.com/Code/Java/Network-Protocol/DetermineifthegivenstringisavalidIPv4orIPv6address. htm – Tala

+0

Tieni presente che, a meno che X-Forwarded-For non sia impostato da * tuo * server (come BigIP F5), non può essere considerato attendibile in quanto può essere impostato dal client su qualsiasi cosa. – lapkritinis

risposta

15

è possibile creare un InetAddress e verificare se è diventato un IPv4 o IPv6 esempio

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

Mi sembra un po 'imbarazzante, però, e spero che ci sia una soluzione migliore.

+0

Meglio come? Si basa sul JDK piuttosto che su una regex locale. Sembra OK per me. – EJP

+2

Meglio perché non si basa su instanceof. Sarebbe bello avere un metodo in InetAddress che restituisce una costante per indicare la versione utilizzata. – Bex

5

Se sei sicuro di ottenere un IPv4 o IPv6, puoi provare quanto segue. Se hai un nome DNS, questo cercherà di eseguire una ricerca. Ad ogni modo, prova questo:

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

cambiate 'Inet4Address' in' Inet6Address' nella parte 'else'. – tokhi

+0

Fatto, grazie per questo – morgano

0

Grazie a Tala.

Questo è quello che ho provato ad utilizzare di this example con lievi modifiche:

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

Non utilizzare la propria espressione regolare per questo. Utilizzare l'instanceof solution. – EJP

+1

Grazie, sì 'instanceof' è più efficiente. – tokhi

+2

Non ho detto nulla sull'efficienza. È più * corretto * perché è integrato nel JDK anziché essere il tuo codice. – EJP

Problemi correlati