【问题标题】:Java - How to detect IP versionJava - 如何检测 IP 版本
【发布时间】:2013-08-07 11:51:25
【问题描述】:

我通过以下方法获得Client IP 地址:

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

现在我想检测它是IPV4 还是IPV6

【问题讨论】:

  • 您可以使用此处所述的正则表达式java2s.com/Code/Java/Network-Protocol/…
  • 请注意,除非 X-Forwarded-For 由某些 您的 服务器(如 BigIP F5)设置,否则它不能被信任,因为它可以由客户端设置为任何东西。

标签: java servlets network-programming


【解决方案1】:

您可以创建一个 InetAddress 并检查它是否成为 ipv4 或 ipv6 实例

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

不过好像有点尴尬,希望有更好的解决办法。

【讨论】:

  • 如何更好?它依赖于 JDK 而不是本土的正则表达式。对我来说似乎没问题。
  • 更好的是它不依赖于instanceof。如果在 InetAddress 中有一个方法返回一个常量来指示正在使用的版本,那就太好了。
【解决方案2】:

如果您确定获得的是 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

}

【讨论】:

  • 请将else 部分中的Inet4Address 更改为Inet6Address
【解决方案3】:

您可以使用来自 google guava 的 InetAddresses。比如这样:

int addressLength = InetAddresses.forString(ip).getAddress().length;
switch (addressLength) {
    case 4:
        System.out.println("IPv4");
        break;
    case 16:
        System.out.println("IPv6");
        break;
    default:
        throw new IllegalArgumentException("Incorrect ip address length " + addressLength);
}

【讨论】:

  • 我喜欢这个主意,谢谢!它也适用于标准 Java API:java.net.InetAddress.getByName(ip).getAddress().length
  • @YannVo 是的,它可以工作,但我不敢使用java.net.InetAddress,因为它们通常会尝试调用一些系统函数,如正向/反向名称解析。通常在内部使用 InetAddress 测试代码会很痛苦
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-01
  • 2016-03-13
  • 2019-02-18
  • 2013-03-28
  • 2015-09-05
  • 1970-01-01
相关资源
最近更新 更多