Bagaimana untuk mendapatkan alamat IP tempatan dalam Java dengan tepat? Kebanyakan kaedah di Internet adalah InetAddress.getLocalHost().getHostAddress()
. Ini sememangnya boleh mendapatkan alamat IP tempatan, tetapi ia tidak tepat. Kerana satu masalah telah diabaikan, persekitaran rangkaian boleh diubah kad rangkaian yang berbeza pada komputer mempunyai berbilang alamat IP, seperti Lan, WiFi, Bluetooth, tempat liputan, kad rangkaian mesin maya, dsb.
127.xxx.xxx.xxx tergolong dalam alamat "loopback", iaitu, ia hanya boleh dilihat oleh mesin anda sendiri, yang ialah alamat setempat, bandingkan Alamat biasa ialah 127.0.0.1
192.168.xxx.xxx ialah alamat peribadi peribadi (alamat setempat tapak), yang boleh diakses dalam organisasi setempat dan hanya boleh dapat dilihat pada LAN tempatan
Begitu juga, 10.xxx.xxx.xxx, daripada 172.16.xxx.xxx hingga 172.31.xxx.xxx adalah semua alamat peribadi dan juga boleh diakses dalam organisasi
169.254.xxx.xxx tergolong dalam pautan IP tempatan dan tersedia dalam segmen rangkaian berasingan
daripada 224.xxx.xxx .xxx hingga 239.xxx.xxx.xxx tergolong dalam kumpulan Alamat siaran
Special 255.255.255.255 milik alamat siaran
Alamat lain ialah alamat IPv4 awam yang tersedia dari titik ke titik
public static void main(String[] args) throws SocketException { System.out.println( IpUtil.getLocalIp4Address().get().toString().replaceAll("/","")); }
package com.dingwen.test.utils; import org.springframework.util.ObjectUtils; import java.net.*; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Optional; /** * 获取本机IP 地址 * * @author dingwen * 2021.04.28 11:49 */ public class IpUtil { /* * 获取本机所有网卡信息 得到所有IP信息 * @return Inet4Address> */ public static List<Inet4Address> getLocalIp4AddressFromNetworkInterface() throws SocketException { List<Inet4Address> addresses = new ArrayList<>(1); // 所有网络接口信息 Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces(); if (ObjectUtils.isEmpty(networkInterfaces)) { return addresses; } while (networkInterfaces.hasMoreElements()) { NetworkInterface networkInterface = networkInterfaces.nextElement(); //滤回环网卡、点对点网卡、非活动网卡、虚拟网卡并要求网卡名字是eth或ens开头 if (!isValidInterface(networkInterface)) { continue; } // 所有网络接口的IP地址信息 Enumeration<InetAddress> 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<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 networkInterfaces) { throw new RuntimeException(networkInterfaces); } return Optional.empty(); } /* * 获取本地IPv4地址 * @return Inet4Address> */ public static Optional<Inet4Address> getLocalIp4Address() throws SocketException { final List<Inet4Address> inet4Addresses = getLocalIp4AddressFromNetworkInterface(); if (inet4Addresses.size() != 1) { final Optional<Inet4Address> ipBySocketOpt = getIpBySocket(); if (ipBySocketOpt.isPresent()) { return ipBySocketOpt; } else { return inet4Addresses.isEmpty() ? Optional.empty() : Optional.of(inet4Addresses.get(0)); } } return Optional.of(inet4Addresses.get(0)); } }
import java.net.*; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Objects; import java.util.Optional; /** * 获取本机IP 地址 */ public class IpUtil { /* * 获取本机所有网卡信息 得到所有IP信息 * @return Inet4Address> */ public static List<Inet4Address> getLocalIp4AddressFromNetworkInterface() throws SocketException { List<Inet4Address> addresses = new ArrayList<>(1); // 所有网络接口信息 Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces(); if (Objects.isNull(networkInterfaces)) { return addresses; } while (networkInterfaces.hasMoreElements()) { NetworkInterface networkInterface = networkInterfaces.nextElement(); //滤回环网卡、点对点网卡、非活动网卡、虚拟网卡并要求网卡名字是eth或ens开头 if (!isValidInterface(networkInterface)) { continue; } // 所有网络接口的IP地址信息 Enumeration<InetAddress> 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<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 networkInterfaces) { throw new RuntimeException(networkInterfaces); } return Optional.empty(); } /* * 获取本地IPv4地址 * @return Inet4Address> */ public static Optional<Inet4Address> getLocalIp4Address() throws SocketException { final List<Inet4Address> inet4Addresses = getLocalIp4AddressFromNetworkInterface(); if (inet4Addresses.size() != 1) { final Optional<Inet4Address> ipBySocketOpt = getIpBySocket(); if (ipBySocketOpt.isPresent()) { return ipBySocketOpt; } else { return inet4Addresses.isEmpty() ? Optional.empty() : Optional.of(inet4Addresses.get(0)); } } return Optional.of(inet4Addresses.get(0)); } }
Atas ialah kandungan terperinci Bagaimana untuk menulis kod untuk mendapatkan alamat IP tempatan di Jawa. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!