Java网络编程(二)—— InetAddress类和NetworkInterface类
- Java网络编程(二)—— InetAddress类和NetworkInterface类
- InetAddress类
- 使用方法
- 可达性
- NetworkInterface类
- 使用方法
- 获取方法
InetAddress类
java.net.InetAddress类是Java对IP地址的高层表示。一般来说,它包括一个主机名和一个IP地址。
使用方法
InetAddress类没有公共构造函数,但是他有一些静态工厂方法来构造InetAddress对象,最常用的就是getByName()方法,例如可以通过下面两种方式:
InetAddress address1 = InetAddress.getByName("www.baidu.com");
InetAddress address2 = InetAddress.getByName("222.31.423.53");
InetAddress提供了获取相应的主机名的两种方法:
- getHostname():首先从DNS缓存中查找与IP地址匹配的主机名,如果不存在,再通过DNS服务器,如果找到,就返回主机名,否则返回IP地址。
- getCanonicalHostName():通过DNS服务器查找与IP地址匹配的主机名,如果找到了,就返回主机名,否则返回IP地址。
上面两种方法的区别在于,getHostname()会首先查找DNS缓存,减少查找DNS服务器的概率,这样做可以提高查找性能。而getCanonicalHostName()总是会查找DNS服务器,确保获得最新版本的主机名。
此外,InetAddress还提供了获取相应的IP地址的两种方法:
- getHostAddress():该方法返回一个字符串,其中包括点分四段格式的IP地址。
- getAddress():它会以网络字节顺序将IP地址作为一个字节数组返回。最高字节(即地址的点分四段格式中的第一个字节)是数组的第一个字节(index=0)。
需要注意的是,第二个方法返回的字节是无符号的,对于JAVA来说,值大于127的字节会被当作负数,因此需要对getAddress()返回的字节做处理,将字节转换为int,下面是一种做法:
int unsighedByte = sighedByte < 0 ? sighedByte + 256 : sighedByte ;
下面是一个简单的小例子
public static void main(String[] args) throws IOException {
InetAddress address1 = InetAddress.getByName("14.215.177.39");
byte[] add = address1.getAddress();
for (int i = 0; i < add.length ; i++)
{
int sign = add[i]<0?add[i]+256 :add[i] ;
System.out.print(sign+" ");
}
}
可达性
InetAddress类有两个isReachable()方法,可以测试一个特定节点对当前主机是否可达(即能否建立一个网络连接)。
public boolean isReachable(int timeout) throws IOException
public boolean isReachable(NetworkInterface networkInterface, int ttl, int timeout) throws IOException
如果远程主机在参数timeout(以ms为单位)指定的时间内做出回应,以上方法返回true,否则返回false。此外,第二个方法还允许从参数指定的本地网络接口建立连接,以及TTL生存时间。TTL(Time To Live)指的是IP数据包被丢弃前允许存在的时间。
public static void main(String[] args) throws IOException {
InetAddress address1 = InetAddress.getByName("www.baidu.com");
System.out.println(address1.isReachable(4000));//true
InetAddress address2 = InetAddress.getByName("www.google.com");
System.out.println(address2.isReachable(4000));//false
}
NetworkInterface类
NetworkInterface类表示一个本地的IP地址,这可以是一个物理接口,如额外的以太网卡(常见于防火墙和路由器),也可以是一个虚拟接口,与机器的其他IP地址绑定到用一个物理硬件。
使用方法
NetworkInterface有两个构造自身实例的静态工厂方法:
- public static NetworkInterface getByName(String name) 表示有指定名字的网络接口
- public static NetworkInterface getByInetAddress(InetAddress address) 表示与指定IP地址绑定的网络接口。
此外,NetworkInterface还提供了一个getNetworkInterfaces()函数,该方法会返回一个java.util.Enumeration,他会列出本地主机上所有的网络接口。下面这个例子就是使用这个方法输出本地所有的网络接口以及网络接口地址。
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();
}
}
}
}
获取方法
有了NetworkInterface对象,就可以查询其IP地址和名字。
public Enumeration getInetAddresses()
一个网络接口可以绑定多个IP地址(不过这种情况现在不常见了)。该方法返回一个java.util.Enumeration,其中对于与这个接口绑定的每一个IP地址都包含一个InetAddress。
public static void main(String[] args) throws Exception {
NetworkInterface ni = NetworkInterface.getByName("eth0");
Enumeration address = ni.getInetAddresses();
while (address.hasMoreElements()) {
System.out.println(address.nextElement());
}
}