文章目录
InetAddress(ip)
-
IP地址是IP使用的32位(IPv4)或者128位(IPv6)位无符号数字,它是传输层协议
TCP,UDP
的基础。 -
InetAddress是
Java对计算机IP及DNS的封装
,用于标识网络上的硬件资源(如:IP,主机名,域名等
),几乎所有的Java网络相关的类都和它有关系,例如:serversocket,socket,URL,DataGramSocket,DataGRamPacket
等。 -
InetAddress对域名进行解析是
使用本地机器配置
或者网络命名服务(如域名系统(Domain Name System,DNS)
和网络信息服务(Network Information Service,NIS))
来实现。对于DNS来说,本地需要向DNS服务器
发送查询的请求,然后服务器根据一系列的操作,返回对应的IP地址,为了提高效率,通常本地会缓存一些主机名与IP地址的映射,这样访问相同的地址,就不需要重复发送DNS请求了。 -
在java.net.InetAddress类同样采用了这种策略。
在默认
情况下,会缓存一段有限时间的映射,对于主机名解析不成功的结果,会缓存非常短的时间(10秒)来提高性能。 -
InetAddress下还有2个子类:
Inet4Address、Inet6Address,
分别代表IPV4,IPV6
地址 -
使用主机名创建一个InetAddress对象,被认为是一种不安全的操作
。因为这需要一个DNS查找,在默认的安全管理控制器下的不可信applet
只允许获取它本机的主机地址以及ip。不允许不可信代码由任何其他主机名创建InetAddress对象。不可信的代码不允许对第三方主机完成任意查找。
InetAddress数据结构
InetAddress实现了Serializable接口,其对象可序列化
创建InetAddress
InetAddress类没有提供返回构造函数
,所以不能用new(来创建
,而只可以调用静态方法getLocalHost()、getByName()、getByAddress() getAllByName()
等来生成InetAddress类的实例。
方法 | 说明 |
---|---|
InetAddress.getLocalHost() | 获取本机的InetAddress,如果获取不到(可能是安全问题)就会返回 地址:127.0.0.1 和 主机名:localhost,如果获取不到主机名就返回ip |
InetAddress.getByName(String host) | 根据ip/域名/主机名 创建InetAddress对象,根据域名查找主机的IP地址(由于可能有多个服务器,ip地址并不是唯一的,要想获取准确的,还需要获取所有的地址才行) |
InetAddress.getAllByName(String host) | 取该主机的所有的地址,返回一个InetAddress[] 对象 |
InetAddress.getByAddress(byte[] addr) | 据 ip字节数组创建 InetAddress 对象 |
InetAddress.getByAddress(String host, byte[] addr) | 根据域名和 ip字节数组创建 InetAddress 对象 |
InetAddress.getLoopbackAddress() |
如果ip/域名/主机名不能解析成一个InetAddress对象,将会抛出一UnknownHostException异常。
示例代码:
//根据域名创建InetAddress对象
InetAddress addr1 = InetAddress.getByName("www.baidu.com");
//[HostName : www.baidu.com] [HostAddress: 220.181.112.244]
//根据ip创建InetAddress对象
InetAddress addr2 = InetAddress.getByName("220.181.112.244");
//[HostName : 220.181.112.244] [HostAddress: 220.181.112.244]
//如果获取不到主机名就返回ip
//根据主机名创建InetAddress对象
InetAddress addr3 = InetAddress.getByName("IFC-PCB-094");
//[HostName : IFC-PCB-094] [HostAddress: 192.168.3.249]
//获取本机的InetAddress,如果获取不到(可能是安全问题)就会返回 地址:127.0.0.1 和 主机名:localhost
InetAddress addr4 = InetAddress.getLocalHost();
//[HostName : IFC-PCB-094] [HostAddress: 192.168.3.249]
//根据 ip字节数组创建 InetAddress 对象
//public static InetAddress getByAddress(byte[] addr)
InetAddress addr = InetAddress.getByAddress(new byte[]{-64,-88,0,1});
//[HostName : jijs] [HostAddress: 192.168.0.1]
//根据域名和 ip字节数组创建 InetAddress 对象
InetAddress addr = InetAddress.getByAddress("jijs",new byte[]{-64,-88,0,1});
//[HostName : jijs] [HostAddress: 192.168.0.1]
//获取该主机的所有的地址,返回一个InetAddress[] 对象
//public static InetAddress[] getAllByName(String host)
InetAddress[] addr = InetAddress.getAllByName("www.baidu.com");
for (InetAddress inetAddress : addr) {
System.out.println(inetAddress);
}
//输出:
//www.baidu.com/220.181.112.244
//www.baidu.com/220.181.111.188
InetAddress类常用方法
方法 | 说明 |
---|---|
public String getHostName() | 获取此IP地址的主机名 |
public String getHostAddress() | 获取InetAdress对象所包含的IP地址 |
public String getCanonicalHostName() | 获取主机名(每次方法都解析DNS去获取主机名,而不从缓存中获取) |
public byte[] getAddress() | 获取以字节数组形式的ip地址 |
示例代码:
/**
* @throws UnknownHostException
* @throws MalformedURLException
*/
public static void main(String[] args) throws UnknownHostException{
//使用getLocalHost方法创建InetAddress对象
InetAddress addr = InetAddress.getLocalHost();//获取本机
System.out.println(addr.getHostAddress()); //ip:192.168.1.100
System.out.println(addr.getHostName()); //计算机名
//根据域名得到InetAddress对象
addr = InetAddress.getByName("www.baidu.com");
System.out.println(addr.getHostAddress()); //返回 百度服务器的ip:14.215.177.39
System.out.println(addr.getHostName()); //主机名:www.baidu.com
InetAddress.getLoopbackAddress();
//根据ip得到InetAddress对象
addr = InetAddress.getByName("4.215.177.39");
System.out.println(addr.getHostAddress()); //返回 163服务器的ip:61.135.253.15
System.out.println(addr.getHostName()); //输出ip而不是域名。如果这个IP地 址不存在或DNS服务器不允许进行IP地址和域名的映射,getHostName方法就直接返回这个IP地址。
}
执行结果:
本机主机名与ip查询方式
InetAddress地址类型
以下使用InetAddress实例对象调用
isMulticastAddress()
当IP地址是广播地址(MulticastAddress)时返回true,否则返回false。
通过广播地址可以向网络中的所有计算机发送信息,而不是只向一台特定的计算机发送信息。IPv4的广播地址的范围是224.0.0.0 ~ 239.255.255.255.IPv6的广播地址第一个字节是FF,其他的字节可以是任意值。
isAnyLocalAddress()
当IP地址是通配符地址时返回true,否则返回false。
IPv4的通配符地址是0.0.0.0
IPv6的通配符地址是0:0:0:0:0:0:0:0,也可以简写成::。
isLoopbackAddress()
当IP地址是loopback地址时返回true,否则返回false。
loopback地址就是代表本机的IP地址。
IPv4的loopback地址的范围是127.0.0.0 ~ 127.255.255.255,也就是说,只要第一个字节是127,就是lookback地址。如127.1.2.3、127.0.200.200都是loopback地址。
IPv6的loopback地址是0:0:0:0:0:0:0:1,也可以简写成::1
isLinkLocalAddress()
当IP地址是本地连接地址(LinkLocalAddress)时返回true,否则返回false。
IPv4的本地连接地址的范围是169.254.0.0 ~ 169.254.255.255。
IPv6的本地连接地址的前12位是FE8,其他的位可以是任意取值,如FE88::和FE80::ABCD::都是本地连接地址。
isSiteLocalAddress()
当IP地址是地区本地地址(SiteLocalAddress)时返回true,否则返回false。(是不是内网ip)
IPv4的地址本地地址分为三段:10.0.0.0 ~ 10.255.255.255、172.16.0.0 ~ 172.31.255.255、192.168.0.0 ~ 192.168.255.255。(企业内部或个人内部的局域网内部的ip都应该在此三个网段内)
IPv6的地区本地地址的前12位是FEC,其他的位可以是任意取值,如FED0:: 和 FEF1:: 都是地区本地地址。
isMCGlobal()
当IP地址是全球范围的广播地址时返回true,否则返回false。
全球范围的广播地址可以向Internet中的所有的计算机发送信息。
IPv4的广播地址除了224.0.0.0和第一个字节是239的IP地址都是全球范围的广播地址。
IPv6的全球范围的广播地址中第一个字节是FF,第二个字节的范围是0E ~ FE,其他的字节可以是任意值,如FFBE::、FF0E::都是全球范围的广播地址。
isMCNodeLocal()
当IP地址是本地接口广播地址时返回true,否则返回false。
本地接口广播地址不能将广播信息发送到产生广播信息的网络接口,即使是同一台计算机的另一个网络接口也不行。所有的IPv4广播地址都不是本地接口广播地址。IPv6的本地接口广播地址的第一个字节是FF,第二个节字的范围是01 ~ F1,其他的字节可以是任意值,如FFB1::、FF01:A123::都是本地接口广播地址。
isMCLinkLocal()
当IP地址是子网广播地址时返回true,否则返回false。
使用子网的广播地址只能向子网内的计算机发送信息。
IPv4的子网广播地址的范围是224.0.0.0 ~ 224.0.0.255。
IPv6的子网广播地址的第一个字节是FF,第二个字节的范围是02 ~ F2,其他的字节可以是任意值,如FFB2:: 和 FF02:ABCD:: 都是子网广播地址。
isMCSiteLocal()
当IP地址是站点范围的广播地址时返回true,否则返回false。
使用站点范围的广播地址,可以向站点范围内的计算机发送广播信息。
IPv4的站点范围广播地址的范围是239.255.0.0 ~ 239.255.255.255,如239.255.1.1、239.255.0.0都是站点范围的广播地址。
IPv6的站点范围广播地址的第一个字节是FF,第二个字节的范围是05 ~ F5,其他的字节可以是任意值,如FF05:: 和 FF45:: 都是站点范围的广播地址。
isMCOrgLocal()
当IP地址是组织范围的广播地址时返回ture,否则返回false。
使用组织范围广播地址可以向公司或企业内部的所有的计算机发送广播信息。
IPv4的组织范围广播地址的第一个字节是239,第二个字节不小于192,第三个字节不大于195,如239.193.100.200、239.192.195.0都是组织范围广播地址。
IPv6的组织范围广播地址的第一个字节是FF,第二个字节的范围是08 ~ F8,其他的字节可以是任意值,如FF08:: 和 FF48::都是组织范围的广播地址。
InetSocketAddress(ip+端口)
- InetSocketAddress类主要作用是封装端口 他是在在InetAddress基础上加端口,但它是有构造器的
- 用于实现 IP 套接字地址 (IP 地址+端口号),用于socket 通信
创建InetSocketAddress
方法 | 说明 |
---|---|
public InetSocketAddress(InetAddress addr, int port) | 根据 IP 地址和端口号创建套接字地址 |
public InetSocketAddress(String hostname, int port) | 根据主机名和端口号创建套接字地址 |
InetSocketAddress常用方法
方法 | 说明 |
---|---|
getAddress() | 获取 当前IP+端口对应InetAddress对象 |
getPort() | 获取端口号 |
getHostName() | 获取 主机名 |
toString() | 构造此 InetSocketAddress 的字符串表示形式。(主机名/Ip:端口号) |
示例代码:
@Test
public void testInetSocketAddress() {
try {
//根据ip + 端口创建 InetSocketAddress
InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 9999);
//根据InetAddress + 端口创建
socketAddress = new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 3306);
System.out.println(socketAddress);
//使用 InetSocketAddress 获取 InetAddress
InetAddress inetAddress = socketAddress.getAddress();
System.out.println("主机信息:" + inetAddress);
int port = socketAddress.getPort();
System.out.println("端口号:" + port);
String hostName = socketAddress.getHostName();
System.out.println("主机名:" + hostName);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}