Java 網絡編程(1):使用 NetworkInterface 得到本機在局域網內的 IP 地址

一、問題提出

在使用 Java 開發網絡程序時,有時候咱們須要知道本機在局域網中的 IP 地址。很常見的一種作法是調用本地命令(好比 Windows 上的 ipconfig 命令和 Linux 上的 ifconfig 命令),接着解析本地命令的輸出,最後獲得本機在局域網內的 IP 地址。很明顯,這種作法不夠方便,也不夠 Java。因而引出了 Java 在 JDK1.4 的時候添加的一個類: NetworkInterfacejava

二、尋找方法

顧名思義,NetworkInterface 用於表示一個網絡接口,這能夠是一個物理的網絡接口,也能夠是一個虛擬的網絡接口,而一個網絡接口一般由一個 IP 地址來表示。既然 NetworkInterface 用來表示一個網絡接口,那麼若是能夠得到當前機器全部的網絡接口(包括物理的和虛擬的),而後篩選出表示局域網的那個網絡接口,那就能夠獲得機器在局域網內的 IP 地址。網絡

查看 NetworkInterface 類的全部方法,發現以下兩個方法:spa

public static Enumeration<NetworkInterface> getNetworkInterfaces()

經過 API 文檔可知,使用 getNetworkInterfaces 方法便可獲得當前機器上全部的網絡接口。.net

public Enumeration<InetAddress> getInetAddresses()

經過 API 文檔可知,getInetAddresses 方法返回綁定到該網卡的全部的 IP 地址。(雖然一個網絡接口確實能夠綁定多個 IP 地址,然而一般狀況下,一個網絡接口都是隻對應一個 IP 地址)code

三、實踐

OK,如今讓電腦鏈接上 WiFi,來實踐下 NetworkInterface 的功能。blog

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;

public class NetworkInterfaceTest {

    public static void main(String[] args) throws Exception {
        // 得到本機的全部網絡接口
        Enumeration<NetworkInterface> nifs = NetworkInterface.getNetworkInterfaces();

        while (nifs.hasMoreElements()) {
            NetworkInterface nif = nifs.nextElement();
        
            // 得到與該網絡接口綁定的 IP 地址,通常只有一個
            Enumeration<InetAddress> addresses = nif.getInetAddresses();
            while (addresses.hasMoreElements()) {
                InetAddress addr = addresses.nextElement();
        
                if (addr instanceof Inet4Address) { // 只關心 IPv4 地址
                    System.out.println("網卡接口名稱:" + nif.getName());
                    System.out.println("網卡接口地址:" + addr.getHostAddress());
                    System.out.println();
                }
            }
        }
    }
}

在我機器(Windows10)上運行結果:接口

運行結果

對比使用 ipconfig 命令獲得的結果:ip

ipconfig的結果

能夠發現開發

網卡接口名稱:wlan1
網卡接口地址:192.168.3.5

即爲機器在局域網內的 IP 地址 —— Windows 平臺上局域網的網絡接口以「wlan」開頭。(lo 爲本地迴環地址,eth0 和 eth4 爲 VMware 建立的虛擬地址)文檔

因而咱們能夠寫出一個簡單的在 Windows 機器上得到局域網 IP 地址的方法:

public InetAddress getLANAddressOnWindows() {
    try {
        Enumeration<NetworkInterface> nifs = NetworkInterface.getNetworkInterfaces();
        while (nifs.hasMoreElements()) {
            NetworkInterface nif = nifs.nextElement();

            if (nif.getName().startsWith("wlan")) {
                Enumeration<InetAddress> addresses = nif.getInetAddresses();

                while (addresses.hasMoreElements()) {

                    InetAddress addr = addresses.nextElement();
                    if (addr.getAddress().length == 4) { // 速度快於 instanceof
                        return addr;
                    }
                }
            }
        }
    } catch (SocketException ex) {
        ex.printStackTrace(System.err);
    }
    return null;
}

(該方法沒有考慮 Windows 平臺上有多個網絡接口的名稱以 「wlan」 開頭的狀況,好比你的機器鏈接了 WiFi,而後又使用該機器做爲熱點 —— 不過很容易對兩者進行區分,請有興趣的讀者本身實踐)


在 JDK1.6 時 NetworkInterface 還添加了一個新的方法:

public List<InterfaceAddress> getInterfaceAddresses()

getInterfaceAddresses 方法的做用與 getInetAddresses 方法相似,可是返回的是一個綁定到該網絡接口的全部 InterfaceAddress 的集合。InterfaceAddress 也是 JDK1.6 以後添加的類,相比於 InetAddress 的區別在於它除了具備一個 IP 地址(InetAddress),還包括了該地址對應的廣播地址和掩碼長度。


四、總結

固然,使用 NetworkInterface 類來獲取機器在局域網內的 IP 地址仍是有必定的平臺相關性,可是相比於使用本地命令的方式來講,會更加方便和更加的 Java 。PS:在 Android 平臺上一樣可使用 NetworkInterface 來實現得到機器在局域網內 IP 地址的功能。

相關文章
相關標籤/搜索