资讯专栏INFORMATION COLUMN

Java 网络编程(1):使用 NetworkInterface 获得本机在局域网内的 IP 地址

Carl / 3003人阅读

摘要:问题提出在使用开发网络程序时,有时候我们需要知道本机在局域网中的地址。在平台上同样可以使用来实现获得机器在局域网内地址的功能。

1、问题提出

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

2、寻找方法

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

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

public static Enumeration getNetworkInterfaces()

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

public Enumeration getInetAddresses()

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

3、实践

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

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 nifs = NetworkInterface.getNetworkInterfaces();

        while (nifs.hasMoreElements()) {
            NetworkInterface nif = nifs.nextElement();
        
            // 获得与该网络接口绑定的 IP 地址,一般只有一个
            Enumeration 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 命令得到的结果:

可以发现

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

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

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

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

            if (nif.getName().startsWith("wlan")) {
                Enumeration 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 getInterfaceAddresses()

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

4、总结

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69782.html

相关文章

  • 重拾Java Network Programming(二)InetAddress

    摘要:前言今天,我将梳理在网络编程中很重要的一个类以及其相关的类。这类主机通常不需要外部互联网服务,仅有主机间相互通讯的需求。可以通过该接口获取所有本地地址,并根据这些地址创建。在这里我们使用阻塞队列实现主线程和打印线程之间的通信。 前言 今天,我将梳理在Java网络编程中很重要的一个类InetAddress以及其相关的类NetworkInterface。在这篇文章中将会涉及: InetA...

    daryl 评论0 收藏0
  • Java网络编程(3):使用 UDP 探测域网内特定类型的机器

    摘要:那没有建立连接的情况下,发现房间这个功能是怎么实现的呢首先,既然手机处于局域网中,那么根据手机当前在局域网的地址和子网掩码,就可以获得这个局域网内所有机器的地址的范围。 记得以前我们使用类似快牙这些文件分享工具的时候,一开始就是先在 手机A 上创建一个房间,然后连接上 手机A WiFi 热点的其他手机(即这些手机处于一个局域网内)就可以发现到这个房间并加入到这个房间里面,然后就可以互相...

    focusj 评论0 收藏0
  • 分享代码片段:java中准确地获取本机ip地址(列表)的方法

    摘要:原文链接获取本地的工具获取本地地址,有可能会有多个地址若有多个网卡则会搜集多个网卡的地址 原文链接:https://gist.github.com/pfmiles/9f7273b12b4b486e2e9c package test; import java.net.InetAddress; import java.net.NetworkInterface; import java....

    wujl596 评论0 收藏0
  • JAVA网络程序设计基础(笔记)

    摘要:三端口与套接字端口指一台计算机只有单一的连接到网络的物理连接,所以的数据都通过此连接对内对外送达特定的计算机,这就是端口。三程序设计由上面可知基于的信息传递速度更快。接收数据包使用创建数据包套接字,绑定指定端口。 服务器 网络 客户机 第一部分 一.局域网与因特网 服务器是指提供信息的计算机或程序,...

    PAMPANG 评论0 收藏0
  • Android 指定网络接口收发 Socket 数据

    摘要:用于标识所在多播组的本地接口。其中都是网络接口的唯一标识符号。运行程序,通过抓包后显示发送成功,并抓到了返回数据黑色标记行为发送数据,橙色标记行为接收数据。 上次写了一篇 Android Ping IPv6 地址的教程,这个工作的目的就是想通过 Volte 网络发送 SIP 消息。但是 Android 默认的网络环境是 Wifi、2G/3G/4G, 不会默认通过 Volte 网络发送数...

    wangbinke 评论0 收藏0

发表评论

0条评论

Carl

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<