Java实现Ip地址获取

      • 一、两种实现方式
      • 二、测试结果

一、两种实现方式

package com.lyp;import org.apache.commons.lang3.ObjectUtils;import java.net.*;import java.util.ArrayList;import java.util.Enumeration;import java.util.List;import java.util.Optional;/** * 获取本机IP 地址 * */public class IpUtils {public static void main(String[] args) throws SocketException, UnknownHostException {System.out.println("传统方式-----------hostAddress = " +getTraditionIp());System.out.println( "新方式-----------hostAddress = "+IpUtils.getLocalIp4Address().get().toString().replaceAll("/",""));}/** * 传统方式,非常简单直接通过InetAddress获取,但不准确获取的为虚拟ip * @throws UnknownHostException */public static String getTraditionIp() throws UnknownHostException {InetAddress localHost = InetAddress.getLocalHost();String hostAddress = localHost.getHostAddress();String hostName = localHost.getHostName();return hostAddress;}/* * 获取本机所有网卡信息 得到所有IP信息 * @return Inet4Address> */public static List getLocalIp4AddressFromNetworkInterface() throws SocketException {List addresses = new ArrayList(1);// 所有网络接口信息Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces();if (ObjectUtils.isEmpty(networkInterfaces)) {return addresses;}while (networkInterfaces.hasMoreElements()) {NetworkInterface networkInterface = networkInterfaces.nextElement();//滤回环网卡、点对点网卡、非活动网卡、虚拟网卡并要求网卡名字是eth或ens开头if (!isValidInterface(networkInterface)) {continue;}// 所有网络接口的IP地址信息Enumeration inetAddresses = networkInterface.getInetAddresses();while (inetAddresses.hasMoreElements()) {InetAddress inetAddress = inetAddresses.nextElement();// 判断是否是IPv4,并且内网地址并过滤回环地址.if (isValidAddress(inetAddress)) {addresses.add((Inet4Address) inetAddress);}}}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();}/* * 通过Socket 唯一确定一个IP * 当有多个网卡的时候,使用这种方式一般都可以得到想要的IP。甚至不要求外网地址8.8.8.8是可连通的 * @return Inet4Address> */private static Optional 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 networkInterfaces) {throw new RuntimeException(networkInterfaces);}return Optional.empty();}/* * 获取本地IPv4地址 * @return Inet4Address> */public static Optional getLocalIp4Address() throws SocketException {final List inet4Addresses = getLocalIp4AddressFromNetworkInterface();if (inet4Addresses.size() != 1) {final Optional ipBySocketOpt = getIpBySocket();if (ipBySocketOpt.isPresent()) {return ipBySocketOpt;} else {return inet4Addresses.isEmpty() ? Optional.empty() : Optional.of(inet4Addresses.get(0));}}return Optional.of(inet4Addresses.get(0));}}

二、测试结果