前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java获取本机IP

Java获取本机IP

作者头像
十毛
发布2019-03-27 14:24:59
7.2K0
发布2019-03-27 14:24:59
举报
文章被收录于专栏:用户1337634的专栏

服务器或PC一般都拥有多个网卡,每个网卡拥有一个IP地址,但并不是所有的IP地址能被外部或局域网访问,比如说虚拟机网卡地址等等。也就是说InetAddress.getLocalHost().getHostAddress()的IP不一定是正确的IP。本文介绍两种方式,可以在绝对部分场景下获取到想要的IP地址。

通过过滤获取IP地址

过滤回环网卡、点对点网卡、非活动网卡、虚拟网卡并要求网卡名字是eth或ens开头;再过滤回环地址,并要求是内网地址(非外网)

代码语言:javascript
复制
public static List<Inet4Address> getLocalIp4AddressFromNetworkInterface() throws SocketException {
    List<Inet4Address> addresses = new ArrayList<>(1);
    Enumeration e = NetworkInterface.getNetworkInterfaces();
    if (e == null) {
        return addresses;
    }
    while (e.hasMoreElements()) {
        NetworkInterface n = (NetworkInterface) e.nextElement();
        if (!isValidInterface(n)) {
            continue;
        }
        Enumeration ee = n.getInetAddresses();
        while (ee.hasMoreElements()) {
            InetAddress i = (InetAddress) ee.nextElement();
            if (isValidAddress(i)) {
                addresses.add((Inet4Address) i);
            }
        }
    }
    return addresses;
}

/**
 * 过滤回环网卡、点对点网卡、非活动网卡、虚拟网卡并要求网卡名字是eth或ens开头
 *
 * @param ni 网卡
 * @return 如果满足要求则true,否则false
 */
private static boolean isValidInterface(NetworkInterface ni) throws SocketException {
    return !ni.isLoopback() && !ni.isPointToPoint() && ni.isUp() && !ni.isVirtual()
            && (ni.getName().startsWith("eth") || ni.getName().startsWith("ens"));
}

/**
 * 判断是否是IPv4,并且内网地址并过滤回环地址.
 */
private static boolean isValidAddress(InetAddress address) {
    return address instanceof Inet4Address && address.isSiteLocalAddress() && !address.isLoopbackAddress();
}

通过访问外网

当有多个网卡的时候,使用这种方式一般都可以得到想要的IP。甚至不要求外网地址8.8.8.8是可连通的。

代码语言:javascript
复制
private static Optional<Inet4Address> getIpBySocket() throws SocketException {
    try (final DatagramSocket socket = new DatagramSocket()) {
        socket.connect(InetAddress.getByName("8.8.8.8"), 10002);
        if (socket.getLocalAddress() instanceof Inet4Address) {
            return Optional.of((Inet4Address) socket.getLocalAddress());
        }
    } catch (UnknownHostException e) {
        throw new RuntimeException(e);
    }
    return Optional.empty();
}

综合

在实际使用中,为了兼容更多的场景,项目中一般兼容了以上两种方式。

代码语言:javascript
复制
public static Optional<Inet4Address> getLocalIp4Address() throws SocketException {
    final List<Inet4Address> ipByNi = getLocalIp4AddressFromNetworkInterface();
    if (ipByNi.isEmpty() || ipByNi.size() > 1) {
        final Optional<Inet4Address> ipBySocketOpt = getIpBySocket();
        if (ipBySocketOpt.isPresent()) {
            return ipBySocketOpt;
        } else {
            return ipByNi.isEmpty() ? Optional.empty() : Optional.of(ipByNi.get(0));
        }
    }
    return Optional.of(ipByNi.get(0));
}

参考

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.12.20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 通过过滤获取IP地址
  • 通过访问外网
  • 综合
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档