使用 NetworkInterface 获得本机在局域网内的 IP 地址

转载于: https://segmentfault.com/a/1190000007462741

1、问题提出

在使用 Java 开发网络程序时,有时候我们需要知道本机在局域网中的 IP 地址。很常见的一种做法是调用本地命令(比如 Windows 上的 ipconfig 命令和 Linux 上的 ifconfig 命令),接着解析本地命令的输出,最后得到本机在局域网内的 IP 地址。很明显,这种做法不够方便,也不够 Java。于是引出了 Java 在 JDK1.4 的时候添加的一个类: NetworkInterface

2、寻找方法

顾名思义,NetworkInterface 用于表示一个网络接口,这可以是一个物理的网络接口,也可以是一个虚拟的网络接口,而一个网络接口通常由一个 IP 地址来表示。既然 NetworkInterface 用来表示一个网络接口,那么如果可以获得当前机器所有的网络接口(包括物理的和虚拟的),然后筛选出表示局域网的那个网络接口,那就可以得到机器在局域网内的 IP 地址。

查看 NetworkInterface 类的所有方法,发现如下两个方法:

public static Enumeration<NetworkInterface> getNetworkInterfaces()

通过 API 文档可知,使用 getNetworkInterfaces 方法即可得到当前机器上所有的网络接口。

public Enumeration<InetAddress> getInetAddresses()

通过 API 文档可知,getInetAddresses 方法返回绑定到该网卡的所有的 IP 地址。(虽然一个网络接口确实可以绑定多个 IP 地址,然而通常情况下,一个网络接口都是只对应一个 IP 地址)

3、实践

OK,现在让电脑连接上 WiFi,来实践下 NetworkInterface 的功能。

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(&quot;网卡接口名称:&quot; + nif.getName());
                System.out.println(&quot;网卡接口地址:&quot; + addr.getHostAddress());
                System.out.println();
            }
        }
    }
}

}" title="" data-original-title=“复制”>

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

public class NetworkInterfaceTest {

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception </span>{
    <span class="hljs-comment">// 获得本机的所有网络接口</span>
    Enumeration&lt;NetworkInterface&gt; nifs = NetworkInterface.getNetworkInterfaces();

    <span class="hljs-keyword">while</span> (nifs.hasMoreElements()) {
        NetworkInterface nif = nifs.nextElement();
    
        <span class="hljs-comment">// 获得与该网络接口绑定的 IP 地址,一般只有一个</span>
        Enumeration&lt;InetAddress&gt; addresses = nif.getInetAddresses();
        <span class="hljs-keyword">while</span> (addresses.hasMoreElements()) {
            InetAddress addr = addresses.nextElement();
    
            <span class="hljs-keyword">if</span> (addr <span class="hljs-keyword">instanceof</span> Inet4Address) { <span class="hljs-comment">// 只关心 IPv4 地址</span>
                System.out.println(<span class="hljs-string">"网卡接口名称:"</span> + nif.getName());
                System.out.println(<span class="hljs-string">"网卡接口地址:"</span> + addr.getHostAddress());
                System.out.println();
            }
        }
    }
}

}

在我机器(Windows10)上运行结果:

运行结果

对比使用 ipconfig 命令得到的结果:

ipconfig的结果

可以发现

网卡接口名称:wlan1
网卡接口地址:192.168.3.5

即为机器在局域网内的 IP 地址 —— Windows 平台上局域网的网络接口以“wlan”开头。(lo 为本地回环地址,eth0 和 eth4 为 VMware 创建的虚拟地址)

于是我们可以写出一个简单的在 Windows 机器上获得局域网 IP 地址的方法:

}" title="" data-original-title=“复制”>

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

        <span class="hljs-keyword">if</span> (nif.getName().startsWith(<span class="hljs-string">"wlan"</span>)) {
            Enumeration&lt;InetAddress&gt; addresses = nif.getInetAddresses();

            <span class="hljs-keyword">while</span> (addresses.hasMoreElements()) {

                InetAddress addr = addresses.nextElement();
                <span class="hljs-keyword">if</span> (addr.getAddress().length == <span class="hljs-number">4</span>) { <span class="hljs-comment">// 速度快于 instanceof</span>
                    <span class="hljs-keyword">return</span> addr;
                }
            }
        }
    }
} <span class="hljs-keyword">catch</span> (SocketException ex) {
    ex.printStackTrace(System.err);
}
<span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;

}

(该方法没有考虑 Windows 平台上有多个网络接口的名称以 “wlan” 开头的情况,比如你的机器连接了 WiFi,然后又使用该机器作为热点 —— 不过很容易对二者进行区分,请有兴趣的读者自己实践)


在 JDK1.6 时 NetworkInterface 还添加了一个新的方法:

public List<InterfaceAddress> getInterfaceAddresses()

getInterfaceAddresses 方法的作用与 getInetAddresses 方法类似,但是返回的是一个绑定到该网络接口的所有 InterfaceAddress 的集合。InterfaceAddress 也是 JDK1.6 之后添加的类,相比于 InetAddress 的区别在于它除了具有一个 IP 地址(InetAddress),还包括了该地址对应的广播地址和掩码长度。


4、总结

当然,使用 NetworkInterface 类来获取机器在局域网内的 IP 地址还是有一定的平台相关性,但是相比于使用本地命令的方式来说,会更加方便和更加的 Java 。
PS:在 Android 平台上同样可以使用 NetworkInterface 来实现获得机器在局域网内 IP 地址的功能。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在VB.NET中获取局域网中的IP地址,可以使用System.Net.NetworkInformation命名空间中的相关类和方法。 首先,可以使用NetworkInterface类来获取本地计算上的网络接口信息。可以通过NetworkInterface.GetAllNetworkInterfaces方法获取所有网络接口的列表,并遍历该列表来获取每个网络接口的信息。 然后,可以根据每个网络接口的信息,使用IPInterfaceProperties类中的UnicastAddresses属性获取每个接口的单播地址列表。从这个列表中,可以筛选出是IPv4地址、非回环地址、以太网地址等符合条件的IP地址。 最后,将符合条件的IP地址存储在一个集合中,并将其打印出来或进行其他处理。 以下是一个简单的示例代码: ```vb Imports System.Net.NetworkInformation Module Module1 Sub Main() Dim ipAddresses As New List(Of String)() ' 获取所有的网络接口 Dim networkInterfaces As NetworkInterface() = NetworkInterface.GetAllNetworkInterfaces() For Each networkInterface As NetworkInterface In networkInterfaces ' 获取网络接口的IP属性 Dim ipProperties As IPInterfaceProperties = networkInterface.GetIPProperties() ' 获取接口的单播地址列表 Dim unicastAddresses As UnicastIPAddressInformationCollection = ipProperties.UnicastAddresses For Each unicastAddress As UnicastIPAddressInformation In unicastAddresses ' 筛选出IPv4地址、非回环地址和以太网地址 If unicastAddress.Address.AddressFamily = System.Net.Sockets.AddressFamily.InterNetwork AndAlso Not IPAddress.IsLoopback(unicastAddress.Address) AndAlso networkInterface.NetworkInterfaceType = NetworkInterfaceType.Ethernet Then ipAddresses.Add(unicastAddress.Address.ToString()) End If Next Next ' 打印IP地址 For Each ipAddress As String In ipAddresses Console.WriteLine(ipAddress) Next Console.ReadLine() End Sub End Module ``` 运行上述代码,就可以获取到局域网中的IP地址,并将其打印出来。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值