inetaddress.getlocalhost()方法用于獲取本地ip地址,但其可靠性存在問題。
代碼示例:
public static void main(String[] args) throws Exception { InetAddress addr = InetAddress.getLocalHost(); System.out.println("Local HostAddress: " + addr.getHostAddress()); String hostname = addr.getHostName(); System.out.println("Local host name: " + hostname); }
在Mac上運行上述代碼的輸出:
在windows環境下,雖然InetAddress.getLocalHost()方法看起來能夠正常獲取本地IP,但實際上在多網卡協同工作的環境下是不準確的。默認情況下,本機名是localhost,在hosts文件中對應的IP是127.0.0.1,因此通過該函數獲取的IP通常是127.0.0.1。這是因為該函數簡單地讀取/etc/hosts的內容,所以默認返回127.0.0.1,這非常不可靠。因此,不建議在生產環境中使用這種方法。
立即學習“Java免費學習筆記(深入)”;
讓我們來看一下/etc/hosts文件的內容:
獲取本地IP的更可靠方法是使用NetworkInterface類。該類提供了三個方法:getName()用于獲取網絡接口名,getDisplayName()用于獲取網絡接口別名,以及getInetAddresses()用于獲取與網絡接口綁定的所有IP地址。
以下是適用于Windows和linux的通用代碼,用于獲取本機IP:
package test; <p>import Java.io.IOException; import java.net.*; import java.util.Enumeration;</p><p>/**</p><ul><li><p>@author yanZhiHang</p></li><li><p>@date 2023/2/2 11:59 */ public class GetLocalHost { public static void main(String[] args) throws Exception { InetAddress addr = InetAddress.getLocalHost(); System.out.println("Local HostAddress: " + addr.getHostAddress()); String hostname = addr.getHostName(); System.out.println("Local host name: " + hostname); System.out.println("本機ip:" + getIpAddress()); }</p><p>public static String getIpAddress() { try { // 從網卡中獲取IP Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces(); InetAddress ip; while (allNetInterfaces.hasMoreElements()) { NetworkInterface netInterface = allNetInterfaces.nextElement(); // 用于排除回送接口,非虛擬網卡,未在使用中的網絡接口 if (!netInterface.isLoopback() && !netInterface.isVirtual() && netInterface.isUp()) { // 返回和網絡接口綁定的所有IP地址 Enumeration<InetAddress> addresses = netInterface.getInetAddresses(); while (addresses.hasMoreElements()) { ip = addresses.nextElement(); if (ip instanceof Inet4Address) { return ip.getHostAddress(); } } } } } catch (Exception e) { System.err.println("IP地址獲取失敗" + e.toString()); } return ""; } }
注意事項:代碼中返回的是與網絡接口綁定的所有IP地址。在使用docker容器的服務器上,根據上述代碼獲取的可能是Docker對外的網卡IP,這可能會導致獲取到錯誤的IP。此外,在有多個網卡的情況下,也可能影響獲取真正的IP。
為了解決這個問題,因為我的真實目的是驗證輸入的IP是否為本機IP,所以只要證明網絡接口中的所有IP包含輸入的IP即可。以下是改造后的代碼:
public static boolean isLocalHost(String localHost) throws Exception { try { Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces(); while (allNetInterfaces.hasMoreElements()) { NetworkInterface netInterface = allNetInterfaces.nextElement(); if (!netInterface.isLoopback() && !netInterface.isVirtual() && netInterface.isUp()) { Enumeration<InetAddress> addresses = netInterface.getInetAddresses(); while (addresses.hasMoreElements()) { InetAddress ip = addresses.nextElement(); if (null != ip && ip.getHostAddress().contains(localHost)) { return true; } } } } } catch (Exception e) { log.error("校驗IP地址失敗:", e.getCause()); e.printStackTrace(); throw new Exception(e); } return false; }
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END