
com.github.joekerouac.common.tools.net.HostInfo Maven / Gradle / Ivy
The newest version!
// Generated by delombok at Fri Mar 14 11:41:38 CST 2025
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
* file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
* to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package com.github.joekerouac.common.tools.net;
import java.net.*;
import java.util.*;
import java.util.concurrent.TimeUnit;
import com.github.joekerouac.common.tools.cache.Cache;
import com.github.joekerouac.common.tools.cache.impl.FixedTimeoutCache;
import com.github.joekerouac.common.tools.collection.Pair;
import com.github.joekerouac.common.tools.constant.ExceptionProviderConst;
import com.github.joekerouac.common.tools.string.StringUtils;
import com.github.joekerouac.common.tools.util.Assert;
import com.github.joekerouac.common.tools.util.NumberUtil;
/**
* 获取本地IP使用
*
* @since 1.0.0
* @author JoeKerouac
* @date 2022-10-14 14:37:00
*/
public final class HostInfo {
@java.lang.SuppressWarnings("all")
@lombok.Generated
private static final com.github.joekerouac.common.tools.log.Logger LOGGER = com.github.joekerouac.common.tools.log.LoggerFactory.getLogger(HostInfo.class.getName());
/**
* 本地网卡接口刷新时间,单位毫秒,每隔该时间就刷新一次
*/
private static final long REFRESH_TIME = TimeUnit.MINUTES.toMillis(5);
/**
* 默认子网掩码:255.255.255.0
*/
private static final byte[] DEFAULT_SUBNET_MASK = new byte[] {-1, -1, -1, 0};
/**
* IPv4地址长度
*/
private static final int IPV4_LEN = 4;
/**
* 网络不可达的超时时间,单位毫秒
*/
private static final int TIMEOUT = 100;
/**
* A类地址最小值:1.0.0.0
*/
private static final long ADDRESS_A_MIN = 65536;
/**
* A类地址最大值:126.255.255.255
*/
private static final long ADDRESS_A_MAX = 2130706431;
/**
* B类地址最小值:128.0.0.0
*/
private static final long ADDRESS_B_MIN = -2147483648;
/**
* B类地址最大值:191.255.255.255
*/
private static final long ADDRESS_B_MAX = -1073741825;
/**
* C类地址(内网)最小值:192.0.0.0
*/
private static final long ADDRESS_C_MIN = -1073741824;
/**
* C类地址(内网)最大值:223.255.255.255
*/
private static final long ADDRESS_C_MAX = -536870913;
/**
* D类地址(多播地址)最小值:224.0.0.0
*/
private static final long ADDRESS_D_MIN = -536870912;
/**
* D类地址(多播地址)最大值:239.255.255.255
*/
private static final long ADDRESS_D_MAX = -268435457;
/**
* 本机所有网卡地址信息缓存
*/
private static volatile Cache> ALL_HOST_INFO_CACHE;
/**
* hostName
*/
private final String hostName;
/**
* hostAddress
*/
private final String hostAddress;
/**
* 地址的byte表示
*/
private final byte[] address;
/**
* 子网掩码
*/
private final byte[] subnetMask;
/**
* 地址类型
*/
private final IpType type;
/**
* 子网编号
*/
private final int subnetId;
/**
* 地址
*/
private InetAddress inetAddress;
/**
* 该地址对应的网络接口,可能为null
*/
private final NetworkInterface networkInterface;
private HostInfo(InetAddress inetAddress, byte[] subnetMask, NetworkInterface networkInterface) {
this.inetAddress = inetAddress;
this.hostName = inetAddress.getHostName();
this.hostAddress = inetAddress.getHostAddress();
this.address = inetAddress.getAddress();
this.subnetMask = subnetMask;
this.type = getType(address);
this.subnetId = NumberUtil.mergeToInt(address) & ~NumberUtil.mergeToInt(subnetMask);
this.networkInterface = networkInterface;
}
static {
// 初始化
ALL_HOST_INFO_CACHE = new FixedTimeoutCache<>(TIMEOUT, HostInfo::obtainAll);
}
/**
* 获取地址类型
*
* @param address
* IPv4地址
* @return 返回地址类型
*/
public static IpType getType(byte[] address) {
Assert.assertTrue(address != null && address.length == IPV4_LEN, "地址格式不对,目前只能处理IPv4地址,当前数据:" + (address == null ? "null" : Arrays.toString(address)), ExceptionProviderConst.IllegalArgumentExceptionProvider);
long target = NumberUtil.mergeToInt(address);
if (target >= ADDRESS_A_MIN && target <= ADDRESS_A_MAX) {
// A类地址
return IpType.TYPE_A;
} else if (target <= ADDRESS_B_MAX) {
// B类地址
return IpType.TYPE_B;
} else if (target <= ADDRESS_C_MAX) {
// C类地址
return IpType.TYPE_C;
} else if (target <= ADDRESS_D_MAX) {
// D类地址
return IpType.TYPE_D;
} else {
return IpType.TYPE_E;
}
}
/**
* 获取本机所有网卡接口对应的地址(同一个网卡多个地址的场景仅会返回一个地址)
*
* @return 所有网卡接口对应的地址,按照type升序排列,type小的在前边
*/
public static List getAll() {
return ALL_HOST_INFO_CACHE.getTarget();
}
/**
* 计算子网掩码
*
* @param interfaceAddress
* 网络接口地址
* @return 子网掩码
*/
private static byte[] calcSubnetMask(InterfaceAddress interfaceAddress) {
// 计算子网掩码
// 子网掩码长度
short networkPrefixLength = interfaceAddress.getNetworkPrefixLength();
// 子网掩码
int subnetMask = 0;
for (int i = 0, j = 31; i < networkPrefixLength; i++, j--) {
subnetMask = subnetMask | 1 << j;
}
return NumberUtil.splitToByte(subnetMask);
}
/**
* 将点分十进制IPv4地址转换为byte数组,不会进行参数校验,外部注意自己校验参数
*
* @param ip
* ip
* @return 数组
*/
public static byte[] convert(String ip) {
String[] data = ip.trim().split("\\.");
byte[] result = new byte[IPV4_LEN];
for (int i = 0; i < data.length; i++) {
result[i] = Byte.parseByte(data[i]);
}
return result;
}
/**
* 获取所有网卡地址信息
*
* @return 所有网卡地址信息(不包含IPv6网络、本地环回网络、虚拟机网络)
*/
private static List obtainAll() {
List all = new ArrayList<>();
try {
// 获取所有网卡接口
Enumeration networkInterfaceEnumeration = NetworkInterface.getNetworkInterfaces();
List, NetworkInterface>> list = new ArrayList<>();
while (networkInterfaceEnumeration.hasMoreElements()) {
NetworkInterface networkInterface = networkInterfaceEnumeration.nextElement();
// 过滤掉P2P网络和本地环回网络(127.0.0.1)
if (networkInterface.isPointToPoint() || networkInterface.isLoopback()) {
continue;
}
String displayName = StringUtils.getOrDefault(networkInterface.getDisplayName(), "");
// 下面几个肯定是虚拟网络,过滤掉
if (displayName.contains("Hyper-V") || displayName.contains("VirtualBox") || displayName.contains("VMware")) {
continue;
}
// 获取该网卡的所有ip地址(同一个网卡允许有多个IP)
List interfaceAddresses = networkInterface.getInterfaceAddresses();
// 最终使用的接口地址列表
List usedInterfaceAddress = new ArrayList<>();
for (InterfaceAddress interfaceAddress : interfaceAddresses) {
InetAddress inetAddress = interfaceAddress.getAddress();
// 过滤掉ipV6
if (inetAddress instanceof Inet6Address) {
continue;
}
// 过滤掉通配地址(0.0.0.0)
if (inetAddress.isAnyLocalAddress()) {
continue;
}
usedInterfaceAddress.add(interfaceAddress);
}
if (usedInterfaceAddress.size() > 0) {
list.add(new Pair<>(usedInterfaceAddress, networkInterface));
}
}
if (list.size() > 0) {
list.sort(HostInfo::compare);
for (Pair, NetworkInterface> pair : list) {
for (InterfaceAddress interfaceAddress : pair.getKey()) {
InetAddress inetAddress = interfaceAddress.getAddress();
all.add(new HostInfo(inetAddress, calcSubnetMask(interfaceAddress), pair.getValue()));
}
}
} else {
all.add(getLocal());
}
} catch (Throwable e) {
all.add(getLocal());
LOGGER.debug(e, "获取网卡异常");
}
all.sort(HostInfo::compare);
return Collections.unmodifiableList(all);
}
/**
* 比较HostInfo,type小的排前边
*
* @param h1
* HostInfo
* @param h2
* HostInfo
* @return h1.type-h2.type
*/
private static int compare(HostInfo h1, HostInfo h2) {
return h1.type.order - h2.type.order;
}
private static int compare(Pair, NetworkInterface> o1, Pair, NetworkInterface> o2) {
return o1.getValue().getIndex() - o2.getValue().getIndex();
}
/**
* 获取机器信息
*
* @return 机器信息
*/
public static HostInfo getInstance() {
return ALL_HOST_INFO_CACHE.getTarget().get(0);
}
/**
* 获取本地网络信息
*
* @return 本地网络信息
*/
private static HostInfo getLocal() {
InetAddress localhost;
try {
localhost = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
localhost = InetAddress.getLoopbackAddress();
}
return new HostInfo(localhost, DEFAULT_SUBNET_MASK, null);
}
/**
* IP类型
*/
public enum IpType {
TYPE_A(0), TYPE_B(1), TYPE_C(2), TYPE_D(3), TYPE_E(4);
private final int order;
IpType(int order) {
this.order = order;
}
}
/**
* hostName
*/
@java.lang.SuppressWarnings("all")
@lombok.Generated
public String getHostName() {
return this.hostName;
}
/**
* hostAddress
*/
@java.lang.SuppressWarnings("all")
@lombok.Generated
public String getHostAddress() {
return this.hostAddress;
}
/**
* 地址的byte表示
*/
@java.lang.SuppressWarnings("all")
@lombok.Generated
public byte[] getAddress() {
return this.address;
}
/**
* 子网掩码
*/
@java.lang.SuppressWarnings("all")
@lombok.Generated
public byte[] getSubnetMask() {
return this.subnetMask;
}
/**
* 地址类型
*/
@java.lang.SuppressWarnings("all")
@lombok.Generated
public IpType getType() {
return this.type;
}
/**
* 子网编号
*/
@java.lang.SuppressWarnings("all")
@lombok.Generated
public int getSubnetId() {
return this.subnetId;
}
/**
* 地址
*/
@java.lang.SuppressWarnings("all")
@lombok.Generated
public InetAddress getInetAddress() {
return this.inetAddress;
}
/**
* 该地址对应的网络接口,可能为null
*/
@java.lang.SuppressWarnings("all")
@lombok.Generated
public NetworkInterface getNetworkInterface() {
return this.networkInterface;
}
/**
* 地址
*/
@java.lang.SuppressWarnings("all")
@lombok.Generated
public void setInetAddress(final InetAddress inetAddress) {
this.inetAddress = inetAddress;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@lombok.Generated
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof HostInfo)) return false;
final HostInfo other = (HostInfo) o;
if (this.getSubnetId() != other.getSubnetId()) return false;
final java.lang.Object this$hostName = this.getHostName();
final java.lang.Object other$hostName = other.getHostName();
if (this$hostName == null ? other$hostName != null : !this$hostName.equals(other$hostName)) return false;
final java.lang.Object this$hostAddress = this.getHostAddress();
final java.lang.Object other$hostAddress = other.getHostAddress();
if (this$hostAddress == null ? other$hostAddress != null : !this$hostAddress.equals(other$hostAddress)) return false;
if (!java.util.Arrays.equals(this.getAddress(), other.getAddress())) return false;
if (!java.util.Arrays.equals(this.getSubnetMask(), other.getSubnetMask())) return false;
final java.lang.Object this$type = this.getType();
final java.lang.Object other$type = other.getType();
if (this$type == null ? other$type != null : !this$type.equals(other$type)) return false;
final java.lang.Object this$inetAddress = this.getInetAddress();
final java.lang.Object other$inetAddress = other.getInetAddress();
if (this$inetAddress == null ? other$inetAddress != null : !this$inetAddress.equals(other$inetAddress)) return false;
final java.lang.Object this$networkInterface = this.getNetworkInterface();
final java.lang.Object other$networkInterface = other.getNetworkInterface();
if (this$networkInterface == null ? other$networkInterface != null : !this$networkInterface.equals(other$networkInterface)) return false;
return true;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@lombok.Generated
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + this.getSubnetId();
final java.lang.Object $hostName = this.getHostName();
result = result * PRIME + ($hostName == null ? 43 : $hostName.hashCode());
final java.lang.Object $hostAddress = this.getHostAddress();
result = result * PRIME + ($hostAddress == null ? 43 : $hostAddress.hashCode());
result = result * PRIME + java.util.Arrays.hashCode(this.getAddress());
result = result * PRIME + java.util.Arrays.hashCode(this.getSubnetMask());
final java.lang.Object $type = this.getType();
result = result * PRIME + ($type == null ? 43 : $type.hashCode());
final java.lang.Object $inetAddress = this.getInetAddress();
result = result * PRIME + ($inetAddress == null ? 43 : $inetAddress.hashCode());
final java.lang.Object $networkInterface = this.getNetworkInterface();
result = result * PRIME + ($networkInterface == null ? 43 : $networkInterface.hashCode());
return result;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@lombok.Generated
public java.lang.String toString() {
return "HostInfo(hostName=" + this.getHostName() + ", hostAddress=" + this.getHostAddress() + ", address=" + java.util.Arrays.toString(this.getAddress()) + ", subnetMask=" + java.util.Arrays.toString(this.getSubnetMask()) + ", type=" + this.getType() + ", subnetId=" + this.getSubnetId() + ", inetAddress=" + this.getInetAddress() + ", networkInterface=" + this.getNetworkInterface() + ")";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy