概念
IP地址对应在Java中的类是InetAddress类,在了解InetAddress之前先介绍几个概念
- 节点(node)
连接到网络的设备叫节点 - 主机(host)
如果节点是计算机则叫主机 - IP地址
网络中区分节点的唯一数字叫IP地址
InetAddress类
InetAddress是Ipv4地址和Ipv6地址的父类,它同时包含了hostname和IP地址
创建InetAddress对象
它没有公共的构造函数,但是有一个静态工厂方法,这个方法通过连接DNS服务器来解析hostname。
InetAddress address = InetAddress.getByName("www.skybility.com");
下面给出完整的例子
@Testpublic void testGetByName() throws UnknownHostException {
InetAddress address = InetAddress.getByName("www.baidu.com");
System.out.println(address);//www.baidu.com/14.215.177.38
也可以通过IP地址来查询hostname:
InetAddress address = InetAddress.getByName("208.201.239.100");System.out.println(address.getHostName());
不过这个方法不太好使,大多数情况会返回你传入的IP地址。同时,这个方法比getByAddress更加便捷,因为可以传入IP地址的字符串形式。
如果某个域名配置了多个IP地址,可以通过下面的方法得到这些IP地址:
public void testGetAllByName() throws UnknownHostException {try {
InetAddress[] addresses = InetAddress.getAllByName("www.baidu.com");
for (InetAddress address : addresses) {
System.out.println(address);
}
} catch (UnknownHostException ex) {
System.out.println(ex.getMessage());
}
}
输出:
www.baidu.com/14.215.177.39www.baidu.com/14.215.177.38
如果想知道本机地址,可通过getLocalHost来返回
@Testpublic void testGetLocalHost() throws UnknownHostException {
InetAddress address = InetAddress.getLocalHost();
System.out.println(address);//USERCHI-UA6LONB/192.168.5.42
如果你知道数值形式的IP地址,那么就可以通过调用getByAddress来创建对象,通常用来创建hostname无法解析或主机不存在的IP地址。
以下是方法签名:
public static InetAddress getByAddress(byte[] addr) throws UnknownHostExceptionpublic static InetAddress getByAddress(String hostname, byte[] addr) throwspublic void testGetByAddress() throws UnknownHostException {
byte[] address = {14,(byte) 215,(byte)177,39};//byte最大值127
InetAddress lessWrong = InetAddress.getByAddress(address);
System.out.println(lessWrong);// /14.215.177.39
InetAddress lessWrongWithname = InetAddress.getByAddress(
"baidu.com", address);
System.out.println(lessWrongWithname); // baidu.com/14.215.177.39
这个方法不保证hostname和ip地址的关联的正确性,也就是hostname可以任意输入。
InetAddress一旦构造好之后是无法修改的,这样可以使它是线程安全的
Address类型
IP地址常见的类型有,127.0.0.1是本地回环地址(local loopback address);224.0.0.0~239.255.255.255是多播地址(multicast address)。
Java提供了10个方法来检测地址类型:
/*** 返回是否为一个通配符地址(wildcard address:0.0.0.0)
*/
public boolean isAnyLocalAddress()
//返回是否为回环地址
public boolean isLoopbackAddress()
//返回是否为IPV6本地链路地址 前缀FE80::/10
public boolean isLinkLocalAddress()
public boolean isSiteLocalAddress()
/**
*返回是否是多播地址
*/
public boolean isMulticastAddress()
//返回是否为全球多播地址 以FFOE或FF1E开头
public boolean isMCGlobal()
用作服务端,0.0.0.0可表示本机上的任意IPV4地址
0.0.0.0和127.0.0.1的区别?
127.0.0.1 是一个环回地址。并不表示“本机”。0.0.0.0才是真正表示“本网络中的本机”。
在实际应用中,一般我们在服务端绑定端口的时候可以选择绑定到0.0.0.0,这样我的服务访问方就可以通过我的多个ip地址访问我的服务。
比如我有一台服务器,一个外放地址A,一个内网地址B,如果我绑定的端口指定了0.0.0.0,那么通过内网地址或外网地址都可以访问我的应用。但是如果我只绑定了内网地址,那么通过外网地址就不能访问。 所以如果绑定0.0.0.0,也有一定安全隐患,对于只需要内网访问的服务,可以只绑定内网地址。
站点本地地址(SiteLocalAddress)与链路本地地址类似,站点本地地址可被路由器在站点或校园内传播,但无法传播到站点或校园之外。以FEC0:0:0:0开头。
Inet4Address和Inet6Address
它们都继承了InetAddress,分别表示IPv4地址和Ipv6地址。通过检查getAddress()方法返回的字节数组大小可以比instance of 更快的检查InetAddress的具体类型。
NetworkInterface类
它代表了网卡,既可以是物理网卡也可以是虚拟网卡。
工厂方法
该类无法被任意的构造,可通过IP地址,名称或枚举得到该类的实例。
getByName
try {NetworkInterface ni = NetworkInterface.getByName("eth0");
if (ni == null) {
System.err.println("No such interface: eth0");
}else{
System.out.println(ni);//name:eth0 (VirtualBox Host-Only Ethernet Adapter)
}
} catch (SocketException ex) {
System.err.println("Could not list sockets.");
}
getByInetAddress
.getLocalHost();NetworkInterface ni = NetworkInterface.getByInetAddress(address);
System.out.println(ni);//name:eth7 (Intel(R) Ethernet Connection (2) I219-V)
getNetworkInterfaces返回本机所有的网卡:
.getNetworkInterfaces();while (interfaces.hasMoreElements()) {
NetworkInterface ni = interfaces.nextElement();
System.out.println(ni);
输出:
name:lo (Software Loopback Interface 1)name:eth0 (VirtualBox Host-Only Ethernet Adapter)
name:eth1 (VMware Virtual Ethernet Adapter for VMnet8)
name:net0 (Microsoft ISATAP Adapter)
name:net1 (Teredo Tunneling Pseudo-Interface)
name:eth2 (VMware Virtual Ethernet Adapter for VMnet1)
name:net2 (WAN Miniport (L2TP))
...
Get方法
一旦你有一个网卡对象,你就可以通过getInetAddresses()得到绑定在该网卡上的IP地址。
NetworkInterface eth0 = NetworkInterface.getByName("eth0");Enumeration addresses = eth0.getInetAddresses();
while (addresses.hasMoreElements()) {
System.out.println(addresses.nextElement());