Java网络InetAddress 和 NetworkInterface
四 、Internet地址
4.1 InetAddress 类
InetAdderss 类是java对网络地址的上层表示,包括IPv4 和IPv6 。
静态构造方法
- InetAddress.getByName(String hostName / IP) ; 当传入域名时,该静态方法会查询DNS服务,获得对应host-IP映射。得到映射关系后InetAddres会将其缓存到cache中,下一次查询时直接返回。 例子: try { InetAddress address = InetAddress.getByName("www.baidu.com"); System.out.println(address); }catch(UnknownHostNameException e){ e.printStackTrace(); } 运行结果
- InetAddress.getLocalHost(); 先使用DNS服务获取本地主机及IP,若获取失败返回点分四段IP public void getInetAddressByIp(){ try { InetAddress address = InetAddress.getLocalHost(); System.out.println(address); } catch (UnknownHostException e) { e.printStackTrace(); } } 运行结果
- InetAddress.getByAddress( btye []) 构造一个byte数组 如 byte ip [] = new byte[]{107 , 23 , (byte) 216 , (byte) 196} ; 为IP :107.23.216.196 的地址。 通过该方法得到的InetAdderss不需要进行DNS查询
缓存
InetAddress的缓存策略可以用过以下系统变量进行控制
- networkaddress.cache.tll 成功缓存的ip-host映射生存时间
- networkaddress.cache.negtive.tll 失败缓存的生存时间
设置方法java.security.Security.setProperty("networkaddress.cache.ttl", "5");
InetAddress的获得方法
- getHostName() 获取主机名/域名 。当InetAddress是由IP地址产生的,未经过DNS查询,该方法能访问DNS服务(耗时)
- getCanonicalHostName() 不经过缓存,访问DNS服务获取HostName
- byte [] getAddress() 获取IP地址数组。值得注意的是该数组中的元素都是无符号byte类型。处理时需要使用int强转,然后对负数+256,转为>=128的正数。 int unsignedsByte = sighedByte <0 ? signedByte +256 : signedByte; 该方法可以通过IP数组的长度判断该地址是IPv4(length = 4)还是IPv6 (length =4) 。
可达性测试
可以使用InetAddress.isReachable()测试地址是否可达。
原理是使用了IMPC协议。
可以使用默认的网络端口,也可以指定网络端口(NetworkIneterface)和网络跳数(ttl)和过期时间(timeout)。
IntAddress的equles() 和 hashCode()方法
只要IP地址相同(不要求主机名相同),equles为true , hashCode相同。
4.2 NetworkInterface 类
该类表示设备上的一个物理接口或者虚拟接口。
工厂方法
- static NetworkInterface getByName(String InterfaceName) 该方法可以通过传入网卡‘名称’生成与其绑定对象。常见的名称有: 以太网口: eth0 eth1l 回送地址名称: lo wifi网口: ``
- NetworkInterface getByInetAddress(InetAddress address) 通过InetAddress对象(IP地址)定位到某个网口,生成NetworkInterfadce对象
- Enumeration getNetworkInterfaces() 获取所有网口对象 例: public void geatInterList(){ try { Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces(); while (networkInterfaces.hasMoreElements()){ NetworkInterface networkInterface = networkInterfaces.nextElement(); Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses(); // 获取网口上绑定的IP地址 while (inetAddresses.hasMoreElements()){ // 遍历IP InetAddress address = inetAddresses.nextElement(); System.out.println(address); } } } catch (SocketException e) { e.printStackTrace(); } } 运行结果
获取方法
- getInetAddress () 获取网口上绑定的网络地址
- getName() 获取网口名称
- getDisplayName() 获取便于打印的完整名称