NIO学习笔记(七)NetworkInterface常用方法
NIO学习笔记(七)NetworkInterface常用方法
在计算机软件中,实现计算机之间数据通信的方式有很多种。在web开发领域中,实现数据通信时是用的最多的就是HTTP协议,他是B/S架构使用的数据通信协议。虽然HTTP在开发效率上得到了保证,但其实运行效率并不是最高的,因为HTTP属于高层协议,内部封装了很多细节,并且请求request进入web容器内部还要执行容器内部的代码,最后执行具体的业务代码。如果想要实现高效率,高并发的数据通信,高层的HTTP协议显然就不适合了。因此底层的Socket就成为了必须掌握的内容。
Socket不是一种协议,是一种实现计算机通信之间的技术,而HTTP才是协议。如果计算机之间想要相互通信,就必须要使用socket技术,而能够读懂对方传递过来的数据就要依靠HTTP协议。
使用任何的编程语言实现套接字编程,都避免不了要与网络接口进行交互,而在进行网络通信之前要获得网络接口的相关信息就显得十分重要了,如网卡、IP等。本节将介绍如何使用JDK中的NetworkInterface获得网络接口信息。
1、NetworkInterface的常用方法
NetworkInterface类表示一个由名称和分配给此接口的IP地址列表组成的网络接口信息的NetworkInterface类,该类就可以获取Ip信息。
NetworkInterface类包含一个由名称和分配给此接口的IP地址列表组成的网络接口,也就是NetworkInterface
1.1获得网络接口的基本信息
public String getName()方法的作用:取得网络设备在操作系统中的名称。该名称并不能的得到具体设备的相关信息,仅仅只是得到一个代号而已。多数都是以eth开头后面跟着数字。eth代表着以太网Ethernet,它是由Xerox公司创建并有Xerox、英特尔和DEC公司联合开发的基带局域网规范。
public String getDisplayName()方法的作用:取得设备在操作系统中的显示名称,此方法返回的字符串包含厂商的名称和网卡的具体型号等相关信息,此方法返回的信息是对getName()的丰富化。
public int getIndex()方法的作用:获得网络接口的索引。此索引值在不同的操作系统中可能不一样。
public boolean isUp()方法的作用:判断网络接口是否已经开启并正常工作。
public boolean isLoopback方法的作用:判断网络接口是否为localhost回调/回环接口。
什么是localhost回调/回环接口?
如果一个网络设备是localhost回调/回环接口,那么它永远是工作的,并且还是虚拟的,也就是计算机上并不真实存在这样的设备,那么它存在的意义是什么呢?如果一台计算机上并没有物理网卡,但是安装了TOMCAT后又想访问TOMCAT,就可以使用localhost和127.0.0.1来进行访问。这里的localhost和127.0.0.1就是环回地址,没有网卡,使用环回地址就可以访问本地的TOMCAT。
下面我们来说说localhost和127.0.0.1的区别。localhost其实只是一个域名,只有把域名解析成127.0.0.1才能进行数据传递和通信,这个解析的过程其实是由hosts文件完成的,该文件在windows下一般存在于C:\Windows\System32\drivers\etc
接下来我们就把上面那些方法玩一遍
public class NetworkInterfaceDemo {
public static void main(String[] args) throws SocketException {
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
while(networkInterfaces.hasMoreElements()){
NetworkInterface face = networkInterfaces.nextElement();
System.out.println("【1】获得网络设备的名称:"+face.getName());
System.out.println("【2】获得网络设备的显示名称:"+face.getDisplayName());
System.out.println("【3】获得网络设备的索引:"+face.getIndex());
System.out.println("【4】网络设备是否已经开启并运行:"+face.isUp());
System.out.println("【5】是否为回调接口:"+face.isLoopback());
System.out.println();
System.out.println();
}
}
}
1.2获取MTU的大小
public int getMTU()方法的作用就是返回MTU的大小。在网络中以数据包为基本传输单元,可以使用MTU(Maximum Transmission Unit 最大传输单元)来规定网络传输的最大数据包的大小,单位为字节。以太网的网卡MTU大多数默认是1500字节,在IPV6协议中,MTU的范围为1280~65535。MTU设置的字节与传输效率有关,如果MTU设置了大的值,则传输速度很快,因为数据包数量少了,但延迟很大,因为对方需要一点点的处理数据;如果MTU设置了很小的值,则传输的很慢,因为发送的数据包多了。建议不要随意更改MTU,因为有可能造成网络传输数据故障,致使数据传输不完整,发生丢包。
接下来我们来看一个例子
public class MTUDemo {
public static void main(String[] args) {
Enumeration<NetworkInterface> networkInterfaces = null;
try {
networkInterfaces = NetworkInterface.getNetworkInterfaces();
while(networkInterfaces.hasMoreElements()){
NetworkInterface face = networkInterfaces.nextElement();
System.out.println("【1】获得网络设备的名称:"+face.getName());
System.out.println("【2】获得网络设备的显示名称:"+face.getDisplayName());
System.out.println("【3】获得最大传输单元:"+face.getMTU());
System.out.println();
System.out.println();
}
} catch (SocketException e) {
e.printStackTrace();
}
}
}
运行完了以后你就会看到有一些网络设备的MTU为-1,这是因为这些网络接口处在被禁用的情况之下。
1.3子接口的处理
public Enumeration getSubInterface()方法的作用:取得子接口。什么是子接口呢?子接口的作用就是在不添加新的物理网卡的基础上,基于原有的网络接口设备再创建出一个虚拟的网络接口进行通信,这个虚拟网络接口可以理解成为是一个由软件模拟的网卡。Windows操作系统不支持子接口,但是Linux支持。
public boolean isVirtual()方法的作用:判断当前网络接口是否为虚拟子接口。在Linux操作系统上,虚拟子接口作为物理接口的子接口被创建,并给予不同的设置(如ip地址,或者MTU等信息)。通常,虚拟子接口的名称将是父接口的名称加上一个冒号(:),再加上标识该子接口的编号,因为一个物理接口可以存在多个虚拟子接口。
1、虚拟接口就是软件模拟的,没有父网络接口
2、虚拟子接口也是软件模拟的,但是他有父接口
3、虚拟接口不一定是虚拟子接口,但是虚拟子接口一定是虚拟接口
public boolean getParent()方法的作用:获得父接口
1.4获得硬件地址
public byte[] getHardwareAddress()方法的作用:获得网卡的硬件地址。什么是硬件地址?硬件地址也称为物理地址或者叫MAC地址。它用来定义网络设备的位置,也就是网卡设备的唯一ID,采用16进制表示一共48位。MAC地址包含有IEEE的注册管理机构RA负责给不同厂商分配唯一标识,因此,正规厂商出厂的网卡MAC地址永远不会重复。
接下来我们就获取一下本机的mac地址
public class MacAddressDemo {
public static void main(String[] args) throws SocketException {
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
while(networkInterfaces.hasMoreElements()){
NetworkInterface face = networkInterfaces.nextElement();
System.out.println("【1】获得网络设备的名称:"+face.getName());
System.out.println("【2】获得网络设备的显示名称:"+face.getDisplayName());
System.out.print("【3】获得网络设备的物理地址:"+ Arrays.toString(face.getHardwareAddress()));
System.out.println();
System.out.println();
}
}
}
1.5获得ip地址
public Enumeration getInetAddress()方法的作用:获得绑定到此网络设备的InteAddress列表,此方法返回的是泛型Enumeration。
InetAddress类可以表示成互联网协议ip地址,通过InetAddress的若干方法来获取ip的相关信息。一个网络接口可以有若干个ip地址。
InetAddress类代表IP地址,他有两个子类,分别是Inet4Address和Inet6Address分别对应IPV4和IPV6相关信息。
接下来我们来简单使用一下
public class InetAddressDemo {
public static void main(String[] args) throws SocketException {
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
while(networkInterfaces.hasMoreElements()){
NetworkInterface face = networkInterfaces.nextElement();
System.out.println("【1】获得网络设备的名称:"+face.getName());
System.out.println("【2】获得网络设备的显示名称:"+face.getDisplayName());
System.out.print("【3】获得网络接口的InetAddress:");
Enumeration<InetAddress> inetAddresses = face.getInetAddresses();
while (inetAddresses.hasMoreElements()){
InetAddress address = inetAddresses.nextElement();
System.out.println("getCanonicalHostName获取此对象的完全限定域名"+address.getCanonicalHostName());
System.out.println("getHostName获取此对象的主机名"+address.getHostName());
System.out.println("getHostAddress获取此对象的ip地址字符串"+address.getHostAddress());
System.out.println("getAddress获取此对象的原始ip地址"+Arrays.toString(address.getAddress()));
}
System.out.println();
System.out.println();
}
}
}
接下来在介绍几个比较常规的用法
1.5.1获得本地主机和环回地址
static InetAddress getLocalHost()方法的作用:返回本地的主机ip地址信息。如果本地主机拥有多个ip,则getlocalHost方法会返回下标为0的第一个ip。如果想要返回本机的全部ip,就需要使用getAllByName()方法。
public class HostNameDemo {
public static void main(String[] args) throws UnknownHostException {
InetAddress inetAddress = InetAddress.getLocalHost();
System.out.println("localhost的getAddress地址为="+ Arrays.toString(inetAddress.getAddress()));
System.out.println();
System.out.println(" "+inetAddress.getClass().getName());
System.out.println();
System.out.println("inetAddress的getLoopbackAddress地址为"+ Arrays.toString(InetAddress.getLoopbackAddress().getAddress()));
System.out.println();
System.out.println(" "+inetAddress.getClass().getName());
}
}
1.5.2根据主机名获得ip地址
static InetAddress getByName(String host)方法的作用:在给定主机名的情况下确定主机的ip地址。参数host可以是计算机名、IP地址,也可以是域名。
public class GetNameByHost {
public static void main(String[] args) throws UnknownHostException {
//根据百度的域名获得ip
InetAddress baidu = InetAddress.getByName("www.baidu.com");
//获得自己的ip
InetAddress myArea = InetAddress.getByName("localhost");
//自己的计算机名称
InetAddress myName= InetAddress.getByName("DESKTOP-LCJDQL5");
//环回地址
InetAddress myIp = InetAddress.getByName("127.0.0.1");
System.out.println(baidu.getClass().getName()+" "+baidu.getHostAddress());
System.out.println(myArea.getClass().getName()+" "+myArea.getHostAddress());
System.out.println(myIp.getClass().getName()+" "+myIp.getHostAddress());
System.out.println(myName.getClass().getName()+" "+myName.getHostAddress());
}
}