package com.xxl.job.core.util;
|
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
|
import java.io.IOException;
|
import java.net.Inet6Address;
|
import java.net.InetAddress;
|
import java.net.NetworkInterface;
|
import java.net.UnknownHostException;
|
import java.util.Enumeration;
|
import java.util.regex.Pattern;
|
|
/**
|
* ip tool
|
*
|
* @author xuxueli 2016-5-22 11:38:05
|
*/
|
public class IpUtil {
|
private static final Logger logger = LoggerFactory.getLogger(IpUtil.class);
|
|
private static final String ANYHOST_VALUE = "0.0.0.0";
|
private static final String LOCALHOST_VALUE = "127.0.0.1";
|
private static final Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$");
|
|
|
|
private static volatile InetAddress LOCAL_ADDRESS = null;
|
|
// ---------------------- valid ----------------------
|
|
private static InetAddress toValidAddress(InetAddress address) {
|
if (address instanceof Inet6Address) {
|
Inet6Address v6Address = (Inet6Address) address;
|
if (isPreferIPV6Address()) {
|
return normalizeV6Address(v6Address);
|
}
|
}
|
if (isValidV4Address(address)) {
|
return address;
|
}
|
return null;
|
}
|
|
private static boolean isPreferIPV6Address() {
|
return Boolean.getBoolean("java.net.preferIPv6Addresses");
|
}
|
|
/**
|
* valid Inet4Address
|
*
|
* @param address
|
* @return
|
*/
|
private static boolean isValidV4Address(InetAddress address) {
|
if (address == null || address.isLoopbackAddress()) {
|
return false;
|
}
|
String name = address.getHostAddress();
|
boolean result = (name != null
|
&& IP_PATTERN.matcher(name).matches()
|
&& !ANYHOST_VALUE.equals(name)
|
&& !LOCALHOST_VALUE.equals(name));
|
return result;
|
}
|
|
|
/**
|
* normalize the ipv6 Address, convert scope name to scope id.
|
* e.g.
|
* convert
|
* fe80:0:0:0:894:aeec:f37d:23e1%en0
|
* to
|
* fe80:0:0:0:894:aeec:f37d:23e1%5
|
* <p>
|
* The %5 after ipv6 address is called scope id.
|
* see java doc of {@link Inet6Address} for more details.
|
*
|
* @param address the input address
|
* @return the normalized address, with scope id converted to int
|
*/
|
private static InetAddress normalizeV6Address(Inet6Address address) {
|
String addr = address.getHostAddress();
|
int i = addr.lastIndexOf('%');
|
if (i > 0) {
|
try {
|
return InetAddress.getByName(addr.substring(0, i) + '%' + address.getScopeId());
|
} catch (UnknownHostException e) {
|
// ignore
|
logger.debug("Unknown IPV6 address: ", e);
|
}
|
}
|
return address;
|
}
|
|
// ---------------------- find ip ----------------------
|
|
|
private static InetAddress getLocalAddress0() {
|
InetAddress localAddress = null;
|
try {
|
localAddress = InetAddress.getLocalHost();
|
InetAddress addressItem = toValidAddress(localAddress);
|
if (addressItem != null) {
|
return addressItem;
|
}
|
} catch (Throwable e) {
|
logger.error(e.getMessage(), e);
|
}
|
|
try {
|
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
|
if (null == interfaces) {
|
return localAddress;
|
}
|
while (interfaces.hasMoreElements()) {
|
try {
|
NetworkInterface network = interfaces.nextElement();
|
if (network.isLoopback() || network.isVirtual() || !network.isUp()) {
|
continue;
|
}
|
Enumeration<InetAddress> addresses = network.getInetAddresses();
|
while (addresses.hasMoreElements()) {
|
try {
|
InetAddress addressItem = toValidAddress(addresses.nextElement());
|
if (addressItem != null) {
|
try {
|
if(addressItem.isReachable(100)){
|
return addressItem;
|
}
|
} catch (IOException e) {
|
// ignore
|
}
|
}
|
} catch (Throwable e) {
|
logger.error(e.getMessage(), e);
|
}
|
}
|
} catch (Throwable e) {
|
logger.error(e.getMessage(), e);
|
}
|
}
|
} catch (Throwable e) {
|
logger.error(e.getMessage(), e);
|
}
|
return localAddress;
|
}
|
|
|
// ---------------------- tool ----------------------
|
|
/**
|
* Find first valid IP from local network card
|
*
|
* @return first valid local IP
|
*/
|
public static InetAddress getLocalAddress() {
|
if (LOCAL_ADDRESS != null) {
|
return LOCAL_ADDRESS;
|
}
|
InetAddress localAddress = getLocalAddress0();
|
LOCAL_ADDRESS = localAddress;
|
return localAddress;
|
}
|
|
/**
|
* get ip address
|
*
|
* @return String
|
*/
|
public static String getIp(){
|
return getLocalAddress().getHostAddress();
|
}
|
|
/**
|
* get ip:port
|
*
|
* @param port
|
* @return String
|
*/
|
public static String getIpPort(int port){
|
String ip = getIp();
|
return getIpPort(ip, port);
|
}
|
|
public static String getIpPort(String ip, int port){
|
if (ip==null) {
|
return null;
|
}
|
return ip.concat(":").concat(String.valueOf(port));
|
}
|
|
public static Object[] parseIpPort(String address){
|
String[] array = address.split(":");
|
|
String host = array[0];
|
int port = Integer.parseInt(array[1]);
|
|
return new Object[]{host, port};
|
}
|
|
|
}
|