Java 获取本机地址信息

以Java语言实现,主要针对IPv4地址。用于处理本机ip获取和ip是否归属同一网段校验。

工具类源码如下:

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import lombok.extern.slf4j.Slf4j;

/**
 * IPV4工具类
 * 
 * @author jun.chen
 *
 */
@Slf4j
public class IPV4Util {

	private static InetAddress getLocalHost() throws UnknownHostException {
		return Inet4Address.getLocalHost();
	}

	/**
	 * 获取本机IP
	 * 
	 * @return
	 * @throws UnknownHostException
	 */
	public static String getHostAddress() throws UnknownHostException {
		return getLocalHost().getHostAddress();
	}

	/**
	 * 获取本机子网掩码
	 * 
	 * @return
	 * @throws UnknownHostException
	 * @throws SocketException
	 */
	public static String getMaskAddress() throws UnknownHostException, SocketException {
		NetworkInterface networkInterface = NetworkInterface.getByInetAddress(getLocalHost());
		String maskAddress = "";
		for (InterfaceAddress address : networkInterface.getInterfaceAddresses()) {
			InetAddress broadcast = address.getBroadcast();
			if (broadcast instanceof Inet4Address) {
				short mask = address.getNetworkPrefixLength();
				maskAddress = getMaskAddress(mask);
			}
		}
		return maskAddress;
	}

	/**
	 * 判断是否同一网段
	 * 
	 * @param sourceAddress
	 * @return
	 * @throws UnknownHostException
	 * @throws SocketException
	 */
	public static boolean isLocalAreaNetwork(String sourceAddress) throws UnknownHostException, SocketException {
		int sourceValue = getAddressValue(sourceAddress);
		Map<String, List<String>> allAddressMap = getAllAddressMap();
		for (Entry<String, List<String>> entry : allAddressMap.entrySet()) {
			String maskAddress = entry.getKey();
			int maskValue = getAddressValue(maskAddress);
			for (String hostAddress : entry.getValue()) {
				int hostValue = getAddressValue(hostAddress);
				boolean equal = (maskValue & hostValue) == (maskValue & sourceValue);
				log.debug("boolean:{} mask:{} local:{} source:{}", equal, maskAddress, hostAddress, sourceAddress);
				if (equal) {
					return equal;
				}
			}
		}

		return false;
	}

	private static String getMaskAddress(short maskLength) {
		String[] maskIps = new String[4];
		for (int i = 0; i < maskIps.length; i++) {
			int node = (maskLength >= 8) ? 255 : (maskLength > 0 ? (maskLength & 0xff) : 0);
			maskIps[i] = String.valueOf(node);
			maskLength -= 8;
		}
		return String.join(".", maskIps);

	}

	private static Map<String, List<String>> hostAddressMapping;

	private static Map<String, List<String>> getAllAddressMap() throws SocketException, UnknownHostException {
		if (null != hostAddressMapping) {
			return hostAddressMapping;
		}
		log.debug("初始化当前主机子网掩码和IP的关系");
		hostAddressMapping = new HashMap<>();
		Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
		List<InterfaceAddress> addressList = new ArrayList<>();
		while (networkInterfaces.hasMoreElements()) {
			NetworkInterface nextElement = networkInterfaces.nextElement();
			for (InterfaceAddress address : nextElement.getInterfaceAddresses()) {
				InetAddress broadcast = address.getBroadcast();
				if (broadcast instanceof Inet4Address) {
					addressList.add(address);
				}
			}
		}
		Map<Short, List<InterfaceAddress>> groupAddress = addressList.stream()
				.collect(Collectors.groupingBy(InterfaceAddress::getNetworkPrefixLength));
		for (Entry<Short, List<InterfaceAddress>> entry : groupAddress.entrySet()) {
			List<String> list = entry.getValue().stream().map(a -> a.getAddress().getHostAddress())
					.collect(Collectors.toList());
			hostAddressMapping.put(getMaskAddress(entry.getKey()), list);
		}
		log.debug("初始化关系完成");
		return hostAddressMapping;
	}

	private static int getAddressValue(String address) {
		byte[] addr = getAddressBytes(address);
		int address1 = addr[3] & 0xFF;
		address1 |= ((addr[2] << 8) & 0xFF00);
		address1 |= ((addr[1] << 16) & 0xFF0000);
		address1 |= ((addr[0] << 24) & 0xFF000000);
		return address1;
	}

	private static byte[] getAddressBytes(String address) {
		String[] addrs = address.split("\\.");
		int length = addrs.length;
		byte[] addr = new byte[length];
		for (int index = 0; index < length; index++) {
			addr[index] = (byte) (Integer.valueOf(addrs[index]) & 0xff);
		}
		return addr;
	}

}

测试主函数:

public static void main(String[] args) throws UnknownHostException, SocketException {

		String IP = "192.168.148.6";
		System.out.println(String.format("IP:%s 是否处于当前局域网:%s", IP, IPV4Util.isLocalAreaNetwork(IP)));

		IP = "127.0.0.1";
		System.out.println(String.format("IP:%s 是否处于当前局域网:%s", IP, IPV4Util.isLocalAreaNetwork(IP)));

		IP = "192.168.1.1";
		System.out.println(String.format("IP:%s 是否处于当前局域网:%s", IP, IPV4Util.isLocalAreaNetwork(IP)));
	}

测试截图:

对于是否归属统一网段有其他好的建议的欢迎留言。 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艮木@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值