随笔 - 312, 文章 - 14, 评论 - 1393, 引用 - 0
数据加载中……

Java网络编程从入门到精通(11):使用NetworkInterface类获得网络接口信息

本文为原创,如需转载,请注明作者和出处,谢谢!

上一篇:Java网络编程从入门到精通(10):Inet4Address类和Inet6Address类

    JDK1.4开始,Java提供了一个NetworkInterface类。这个类可以得到本机所有的物理网络接口和虚拟机等软件利用本机的物理网络接口创建的逻辑网络接口的信息。

一、创建NetworkInterface对象的两个静态方法

NetworkInerface类和InetAddress一样,也没有public的构造方法。因此,必须通过它的两个静态方法来创建NetworkInterface对象。可以使用两种方法来创建NetworkInterface对象:网络接口名(getByName方法)和IP地址(getByInetAddress方法)

1. getByName方法

这个方法可以通过网络接口名来创建NetworkInterface对象。这个网络接口名并不是计算机名,而是用于标识物理或逻辑网络接口的名字,一般是由操作系统设置的。网络接口名在大多数操作系统上(包括WindowsLinuxUnix)是以eth开头,后面是网络接口的索引号,从0开始。如本机安了三块网卡,那么网络接口名就依次是eth0eth1eth2NetworkInterface对象的toString方法可以返回网络接口的名称、显示名和这个网络接口上绑字的所有IP地址等信息。当网络接口名不存在时,getByName返回nullgetByName方法定义如下:

    public static NetworkInterface getByName(String name) throws SocketException

下面的代码是一个显示指定网络接口信息的程序,网络接口名通过命令行参数传入。

package mynet;

import java.net.*;

public class MyNetworkInterface1
{
    
public static void main(String[] args) throws Exception
    {
        
if (args.length == 0)
            
return;
        NetworkInterface ni 
= NetworkInterface.getByName(args[0]);
        System.out.println((ni 
== null? "网络接口不存在!" : ni);
    }
}

  • 测试1

执行如下命令:

java mynet.MyNetworkInterface1 eth0

运行结果:

name:eth0 (Realtek RTL8139 Family PCI Fast Ethernet NIC) index: 4 addresses:
/
192.168.18.10;
/192.168.18.20;
  • 测试2

执行如下命令:

java mynet.MyNetworkInterface1 abcd

运行结果:

网络接口不存在!

2. getByInetAddress方法

    除了可以使用网络接口名来得到网络接口的信息,还可以利用getByInetAddress方法来确定一个IP地址属于哪一个网络接口。由于getByInetAddress方法必须使用一个InetAddress对象封装的IP地址来作为参数,因此,在使用getByInetAddress方法之前,必须先创建一个InetAddress对象。但要注意不能使用远程的IP的域名来创建InetAddress对象,否则getByInetAddress将返回nullgetByInetAddress方法的定义如下:

public static NetworkInterface getByInetAddress(InetAddress addr) throws SocketException

    下面代码可以确定一个IP地址属于哪一个网络接口,这个IP地址通过命令行参数传入。

package mynet;

import java.net.*;

public class MyNetworkInterface2
{

    
public static void main(String[] args) throws Exception
    {
        
if(args.length == 0return;
        InetAddress local 
= InetAddress.getByName(args[0]);
        NetworkInterface ni 
= NetworkInterface.getByInetAddress(local);
        System.out.println((ni 
== null? "本机不存在此IP地址!" : ni);        
    }
}

  • 测试1

执行如下命令:

java mynet.MyNetworkInterface2 127.0.0.1

运行结果:

name:lo (MS TCP Loopback interface) index: 1 addresses:
/
127.0.0.1;
/0:0:0:0:0:0:0:1;
  • 测试2

执行如下命令:

java mynet.MyNetworkInterface2 218.61.151.22

运行结果:

name:ppp0 (WAN (PPP/SLIP) Interface) index: 0 addresses:
/
218.61.151.22;

    测试2使用的IP地址218.61.151.22ADSL连接临时分配给本机的IP地址,因此,运行结果返回的ppp0ADSL网络接口。

二、得到本机所有的网络接口

    NetworkInterface可以通过getNetworkInterfaces方法来枚举本机所有的网络接口。我们也可以利用getNetworkInterfaces得到的网络接口来枚举本机的所有IP地址。当然,也可以通过InetAddress类的getAllByName来得到本机的所有IP地址。但getNetworkInterfaces方法可以按网络接口将这些IP地址进行分组,这对于只想得到某个网络接口上的所有IP地址是非常有用的。getNetworkInterfaces方法的定义如下:

public static Enumeration<NetworkInterface> getNetworkInterfaces() throws SocketException

    下面代码演示了如何使用getNetworkInterfaces方法得到本机所有的网络接口。

package mynet;

import java.net.*;
import java.util.*;

public class MyNetworkInterface3
{
    
public static void main(String[] args) throws Exception
    {
        Enumeration
<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
        
while (nis.hasMoreElements())
            System.out.println(nis.nextElement());
    }
}

运行结果(部分):

name:lo (MS TCP Loopback interface) index: 1 addresses:
/
127.0.0.1;
/0:0:0:0:0:0:0:1;
name:eth0 (Realtek RTL8139 Family PCI Fast Ethernet NIC ) index: 4 addresses:
/
192.168.18.10;
/192.168.18.20;
name:ppp0 (WAN (PPP/SLIP) Interface) index: 0 addresses:
/
218.61.151.22;
 

    上面的运行结果只是一种可能的结果,读者在运行上面的程序时根据本机的硬件和软件的配置不同,运行结果可能会有所不同。

三、NetworkInterface类的Getter方法

    NetworkInterface类提供了三个方法可以分别得到网络接口名(getName方法)、网络接口别名(getDisplayName方法)以及和网络接口绑定的所有IP地址(getInetAddresses方法) 

1. getName方法

这个方法用来得到一个网络接口的名称。这个名称就是使用getByName方法创建NetworkInterface对象时使用的网络接口名,如eth0ppp0等。getName方法的定义如下:

public String getName()

2. getDisplayName方法

这个方法可以得到更容易理解的网络接口名,也可以将这个网络接口名称为网络接口别名。在一些操作系统中(如Unix),getDisplayName方法和getName方法的返回值相同,但在WindowsgetDisplayName方法一般会返回一个更为友好的名字,如Realtek RTL8139 Family PCI Fast Ethernet NICgetDisplayName方法的定义如下:

public String getDisplayName()

3. getInetAddresses方法

NetworkInterface类可以通过getInetAddresse方法以InetAddress对象的形式返回和网络接口绑定的所有IP地址。getInetAddresses方法的定义如下:

public Enumeration<InetAddress> getInetAddresses()

上面的代码演示了如果使用上述三个Getter方法。

package mynet;

import java.net.*;
import java.util.*;

public class MyNetworkInterface4
{
    
public static void main(String[] args) throws Exception
    {
        
if (args.length == 0)
            
return;
        NetworkInterface ni 
= NetworkInterface.getByName(args[0]);
        System.out.println(
"Name: " + ni.getName());
        System.out.println(
"DisplayName: " + ni.getDisplayName());
        Enumeration
<InetAddress> addresses = ni.getInetAddresses();
        
while (addresses.hasMoreElements())
            System.out.println(addresses.nextElement().getHostAddress());
    }
}

1. 测试

执行如下命令:

java mynet.MyNetworkInterface4 eth0

运行结果:

Name: eth0
DisplayName: Realtek RTL8139 Family PCI Fast Ethernet NIC
192.168.18.10
192.168.18.20

下一篇:Java网络编程从入门到精通(12):使用isReachable方法探测主机是否可以连通



Android开发完全讲义(第2版)(本书版权已输出到台湾)

http://product.dangdang.com/product.aspx?product_id=22741502



Android高薪之路:Android程序员面试宝典 http://book.360buy.com/10970314.html


新浪微博:http://t.sina.com.cn/androidguy   昵称:李宁_Lining

posted on 2009-05-08 08:53 银河使者 阅读(10253) 评论(9)  编辑  收藏 所属分类: java 原创网络编程

评论

# re: Java网络编程从入门到精通(11):使用NetworkInterface类获得网络接口信息  回复  更多评论   

你这个系列是对JDK文档的详细说明。网络编程难点不在API的使用上,这个看看文档,看看tutorial就知道了。网络编程的难点在于理解各种网络IO模型,熟悉TCP/IP协议,熟悉并发模型,知道网络编程的性能关键要素,并对各种开源网络框架的优劣势有个比较清晰的认识等等。API使用反而是最不重要的。
2009-05-08 11:28 | dennis

# re: Java网络编程从入门到精通(11):使用NetworkInterface类获得网络接口信息  回复  更多评论   

我这个系列文章才刚开始,估计得有上百篇文章,还没进入大规模编程的阶段。另外,你说的熟悉什么 TCP/IP协议、并发模型这些都有些抽象。实际上,不管是网络编程,还是多核编程,关键看你做出来什么。至于熟悉这个或那个,只是知识量而已。只有做出有影响力的产品才是真的。还有并不一定技术高深就是好的,关键看能提供多少用户价值。
2009-05-08 11:46 | 银河使者

# re: Java网络编程从入门到精通(11):使用NetworkInterface类获得网络接口信息  回复  更多评论   

期待LZ这个系列文章的早日完成!
2009-05-08 12:21 | 学者

# re: Java网络编程从入门到精通(11):使用NetworkInterface类获得网络接口信息  回复  更多评论   

@银河使者
我是在说网络编程,你在跟我说做产品,呵呵,我们说的不是一个东西。我是认为网络编程的学习着重点应该在我说的这几个方面,网络编程不仅仅是熟悉JAVA提供的api,难道换了种语言你就不会网络编程了?我强调的是学习重点。
2009-05-08 15:40 | dennis

# re: Java网络编程从入门到精通(11):使用NetworkInterface类获得网络接口信息  回复  更多评论   

@dennis
实际上,学习并没有绝对的重点,不管是理论(如tcp/ip、网络层等)或是api都需要会,不会哪个都写不出优秀的程序。但个人认为在学习理论之前,应该先了解一下api,也就是说,在写出优秀的程序之前,先要能写出程序。如果连helloword都写不出来,又怎么谈高质量的程序呢?而本系列文章就是先让读者能写出程序,至于写出优秀的程序,那并不是本系列文章的目的。
还有就是,学习网络编程的重点应该放在实践上,不管是学的tcp/ip,还是学的api、socket这些东西,都需要将它们转换成代码才可以。否则学了只能应付考试。因此,无论是api,还是网络理论,都应该是重点。另外,api可不是很简单的。并不是有一堆方法,调用就完了。有很多参数和调用方法是和理论联系非常紧密的。因此,最好理论和api一起学,否则用什么实践呢?直接访问网卡驱动?
2009-05-08 16:26 | 银河使者

# re: Java网络编程从入门到精通(11):使用NetworkInterface类获得网络接口信息  回复  更多评论   

学习了,正好准备学习网络编程,阁下的这个系列对我很有用,谢谢啦,期待大作的完成,顺便问下,能不能交换下链接

您的链接我已经帮您做好了,我的链接是:
名称:John Winning's Blog
网址:http://www.godupgod.com
2009-05-30 22:59 | John Winning

# re: Java网络编程从入门到精通(11):使用NetworkInterface类获得网络接口信息[未登录]  回复  更多评论   

好东东!!!
多谢分享!!!
2009-06-04 10:40 | Java爱好者

# re: Java网络编程从入门到精通(11):使用NetworkInterface类获得网络接口信息  回复  更多评论   

hao
2013-04-21 14:34 | ll

# re: Java网络编程从入门到精通(11):使用NetworkInterface类获得网络接口信息  回复  更多评论   

绝对的好东西,我是greenhand。顶楼主。有个小纠结:没找到目录--只有上一篇,下一篇。有点不方便。想都看
2013-04-21 14:36 | cxw

只有注册用户登录后才能发表评论。


网站导航: