原文地址: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 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<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 命令得到的结果:

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 getInterfaceAddresses()

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

4、总结

当然,使用 NetworkInterface 类来获取机器在局域网内的 IP 地址还是有一定的平台相关性,但是相比于使用本地命令的方式来说,会更加方便和更加的 Java 。

PS:在 Android 平台上同样可以使用 NetworkInterface 来实现获得机器在局域网内 IP 地址的功能。

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

  1. 网络编程懒人入门(九):通俗讲解,有了IP地址,为何还要用MAC地址?

    1.前言 标题虽然是为了解释有了 IP 地址,为什么还要用 MAC 地址,但是本文的重点在于理解为什么要有 IP 这样的东西.本文对读者的定位是知道 MAC 地址是什么,IP 地址是什么. (本文同步 ...

  2. JAVA网络编程【转】出处不详

    网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编 ...

  3. 【转】JAVA 网络编程

    网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编 ...

  4. Java网络编程技术1

    1. Java网络编程常用API 1.1 InetAddress类使用示例 1.1.1根据域名查找IP地址 获取用户通过命令行方式指定的域名,然后通过InetAddress对象来获取该域名对应的IP地 ...

  5. java网络编程+通讯协议的理解

    参考: http://blog.csdn.net/sunyc1990/article/details/50773014 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很 ...

  6. Java网络编程技术2

    3. UDP数据报通信 UDP通信中,需要建立一个DatagramSocket,与Socket不同,它不存在“连接”的概念,取而代之的是一个数据报包——DatagramPacket.这个数据报包必须知 ...

  7. 20145205 《Java程序设计》实验报告五:Java网络编程及安全

    20145205 <Java程序设计>实验报告五:Java网络编程及安全 实验要求 1.掌握Socket程序的编写: 2.掌握密码技术的使用: 3.客户端中输入明文,利用DES算法加密,D ...

  8. Java 网络编程学习总结

    新手一枚,Java学习中,把自己学习网络编程的知识总结一下,梳理下知识,方便日后查阅,高手莫进. 本文的主要内容: [1]    网络编程认识                [2]  TCP/IP编程 ...

  9. 20145212 实验五《Java网络编程》

    20145212 实验五<Java网络编程> 一.实验内容 1.运行下载的TCP代码,结对进行,一人服务器,一人客户端: 2.利用加解密代码包,编译运行代码,一人加密,一人解密: 3.集成 ...

随机推荐

  1. Html加水印和禁用复制和右键(jquery.watermark.js)

    近期遇到一个需求,需要在页面背景加上自己的水印和禁止用户在页面复制粘贴 解决: 水印使用的是jquery.watermark.js插件,这个插件可以在html背景上加水印,同时可以设置相关属性值. 相 ...

  2. java求两个数中的大数

    java求两个数中的大数 java中的max函数在Math中 应用如下: int a=34: int b=45: int ans=Math.max(34,45); 那么ans的值就是45.

  3. C/S模式简单socket通信

    TCP连接方式 sever.c #include <stdio.h>#include <stdlib.h>#include <sys/socket.h>#inclu ...

  4. ASP.NET CORE-Info:TechEmpower最新一轮的性能测试出炉,ASP.NET Core依旧表现不俗

    ylbtech-ASP.NET CORE-Info:TechEmpower最新一轮的性能测试出炉,ASP.NET Core依旧表现不俗 1.返回顶部 1. TechEmpower在10月30发布最新一 ...

  5. HDU 6628 permutation 1 (暴力)

    2019 杭电多校 5 1005 题目链接:HDU 6628 比赛链接:2019 Multi-University Training Contest 5 Problem Description A s ...

  6. 剑指offer——58数组中数值和下标相等的元素

    题目三: 数组中数值和下标相等的元素. 假设一个单调递增的数组里的每个元素都是整数并且是唯一的.请编程实现一个函数,找出数组中任意一个数值等于其下标的元素.例如,在数组{-3,-1,1,3,5}中,数 ...

  7. VC++ 2010 创建高级Ribbon界面详解(4)

    5.辅助控件 除了前面我们介绍的按钮,工具栏,编辑框等基本控件外,为了支持现代软件对丰厚的界面交互方式的要求,Visual Studio 2010还提供了很多其他的辅助控件,例如我们通常会用到的“上一 ...

  8. 2019年Pandas官方用户调研

    import pandas as pd import seaborn as sns import matplotlib.pyplot as plt %matplotlib inline plt.rcP ...

  9. 使用VBA达到vlookup效果

    Function Desc(ProdNum) Desc = Application.WorksheetFunction.VLookup(ProdNum, Range("myTable&quo ...

  10. hdu6395 /// 优先队列dijkstra

    题目大意: 给定无向图的n m为点数和边数 接下来m行给定u v id表示点u到点v间有一条编号为id的边 当由一条边走到另一条边 而两条边的编号不同时 费用+1 优先队列跑dijkstra最短路 按 ...