2、Internet地址(上)

连接到Internet的设备称为节点

计算机节点称为主机

每个节点或主机至少一个唯一的数来标识,这个节点称为Internet地址或者IP地址

目前大多数IP地址是四字节长,被称为IPv4地址

地址是16字节长,被称为IPv6

两者都是地址的有序序列,和数组一样

他们不是数,他们的顺序也不是具有任何可测或有用的意义

IPv4地址一般些微四个无符号字节,每个字节范围从0-255,最高字节在前

个节点之间用点作分隔符

如153.19.134.132

称为点分四段格式

IPv6地址通常写为冒号分割的8个区块

每个区块都是4个十六进制的数字

2400:cb00:2048:0001:0000:0000:6ca2:c665

前导为0需要写出:2400:cb00:2048:0001:0:0:6ca2:c665

两个冒号标识多个0区块

但是每个地址中双冒号至多出现一次

在IPv4和IPv6的混合网络中

IPv6的最后四个字节有时写为IPv4的点分四段地址

IP地址对于计算机来说很容易记忆

但是对人来说很难记忆

为了避免到处携带记IP地址的通讯录

Interne发明了域名系统

DNS将人们可以记忆的主机名与计算机记忆的IP地址关联在一起

服务器通常至少有一个主机名

客户端往往有一个主机名,但也可能没有

=人们通常使用的Internet标识一个主机名

=准备区分地址和主机名

有些机器有多个名

有时一个名对映射到多个IP地址,这时就要由DNS服务器负载随机选择一台机器来相应各个请求

这个特性在Web网站经常使用

负则将负载分摊到多个系统上

每台连接到Internet的计算机都应当能访问一个称为域名服务器的机器

它通常是一个运行特殊DNS软件的UNIX主机

这种软甲内链接不同主机名和IP地址之间的映射

大多数域名服务器只知道本地网络上的主机地址,以及其他网站中一些域名服务器的地址

如果客户端请求本地之外的一个机器地址,本地域名服务器就会询问远程位置的域名服务器,在将请求发给请求者

大多数情况下,可以使用主机名,而DNS处理向IP地址的转换

只要能连接到一个域名服务器,就不需要担心你的机器、本地域名服务器和Internet其余部分之间传递主机名和地址的有关细节

InetAddress类

java.net.InetAddress类是Java的IP地址的高层表示

大多数网络类都需要使用(Socket、ServerSocket、URL、DatagramSocket、DategramPacket等)

一般的来说,包括主机名和IP地址

创建新的InetAddress对象

InetAddress类没有公共构造函数

实际上InetAddress有一些静态的工厂方法

可以连接到DNS服务器来解析主机名

最长使用InetAddress.getName()

        InetAddress address = InetAddress.getByName("www.baidu.com");
        System.out.println(address);

同时可以本地ping一下

会与本地DNS服务器建立连接

来查找名字和数字地址(若查过,可能在缓存中进行查找)

DNS服务器找不到这个地址就会抛出一个UnknowHostException

还可以按照哦IP地址进行反向查找

可以向InetAddress.getByName()传入一个点分四段地址

        InetAddress address = InetAddress.getByName("208.201.239.100");
        System.out.println(address.getHostName());

如果查找的地址没有对应的主机名

getHostname()就会返回所提供的点分四段地址

有点域名会有多个地址

getHostName()返回哪一个地址是不缺定的

出于某种原因需要得到一个主机的所有地址可以使用getAllByName()返回一个数组

   InetAddress[] addresses = InetAddress.getAllByName("www.oreilly.com");

        for (InetAddress address : addresses){
            System.out.println(address);
        }

getLocalHost()方法会为运行这个代码的主机返回一个InetAddress对象

        InetAddress address = InetAddress.getLocalHost();
        System.out.println(address);

会返回本地的地址主机名和点四分段地址

如果没有连接到Internet,系统没有固定的IP地址或域名,可能会看到localhost和127.0.0.1

如果知道一个数字地址

可以由这个地址创建一个InetAddress对象

不必使用InetAddress.getByAddress()与DNS交互

这个方法可以在不存在或者无法解析的主机创建地址:

第一个getByAddress()工厂方法用一个IP地址创建一个InetAddress对象

第二个InetAddress.getByAddress()方法使用一个IP地址和一个主机名创建InetAddress对象

        byte [] address = {107,23, (byte) 216, (byte) 196};
        InetAddress byAddress = InetAddress.getByAddress(address);

        InetAddress mrChengs = InetAddress.getByAddress("mrchengs.com", address);

这两个方法不能确保这个主机一定在,或者主机名能正确映射到IP地址

只有在传入的字节数组不合法时才会进行抛异常

缓存

 由于DNS查找的开销可能很大

所以InetAddress类会缓存查找的结果

一旦得到一个给定的主机地址,就不会再次查找

即使为同一个主机创建新的InetAddress对象,也不会再次查找地址

只要在程序运行期间IP地址没有改变

负面结果:

有可能刚开始解析一个主机时失败

随后再次进行解析会成功

由于从远程DNS服务器发来的信息还在传输中

第一次尝试超时,然后这个地址到达服务器

所以下一次请求时可用,处于这个原因Java对不成功的DNS查询只缓存10秒

这些时间由

1、networkaddress.cache.ttl

2、networkaddress.cache.negative.ttl控制

第一个指定成功的DNS查询结果在缓存中保留的时间

第二个制定了不成功的查询在缓存中保存的时间

再次查询向的主机会返回相同的值,-1解释为永不过期

除了在InetAddress类中的本地缓存,本地主机、本地域名服务器和Internet上其他地方的DNS

服务器也会缓存何种查询结果

按IP地址进行查询

调用getName()并且提供一个IP地址串作为参数时

会为所有请求的IP地址创建一个InetAddress对象,而不检查DNS

说明:实际上会为不存在也无法连接的主机创建InetAddress对象

由包含IP地址的字符集来创建InetAddress对象时,这个对象的主机名楚世家为这个字符串

只有当请求主机名时(显示的通过getHostname()请求)

才会真正完成主机名的DNS查找

从点四分段法缺点域名地址

如果请求主机名并且完成了一个DNS查找

但是指定IP地址的主机无法找到

那么主机名会保持最初的点分四段字符串

不会抛异常

安全性问题

从主机名创建一个新的InetAddress对象被认为是一个不安全的操作

因为这需要一个DNS查找

在默认安全管理器控制下的不可信applet只允许获得它的初始化主机的IP地址

不允许不可信代码由其他任何其他主机名创建InetAddress对象

不论代码使用InetAddress.getByName()、InetAddress.getAllByName()方法等

不可信代码可以由字符串形式的ip地址构造InetAddress对象

但不会为这样的地址完成DNS查找

由于禁止与代码基之外的主机建立连接,不可信的代码不允许对第三方主机完成任意的DNS查找

任意的DNS查询会打开一个隐藏的通道

通过通道程序可以与第三方主机对话

 获取方法

InetAddress包含四个获取方法:

getHostName()方法返回一个String,其中包含主机名义以及这个InetAddress对象表示的IP地址

如果这台计算机没有主机名或者安全管理器确定主机名,就会返回点分四段格式的数组IP地址

        InetAddress localHost = InetAddress.getLocalHost();
        String name = localHost.getHostName();
        System.out.println(localHost);
        System.out.println(name);

 

getCanonicalHostname()方法也类似,在DNS联系方面更积极一点

getHostName()只是在不知道主机名时才会联系DNS

getCanonicalHostname()知道主机名也会联系DNS

        InetAddress localHost = InetAddress.getLocalHost();
        String name = localHost.getCanonicalHostName();
        System.out.println(localHost);
        System.out.println(name);

如果开始只有一个点分四段IP地址而没有主机名

getCanonicalHostName()方法尤其重要

 getHostAddress()方法返回一个 字符串

其中包括点分四段和的IP地址

        InetAddress localHost = InetAddress.getLocalHost();

        String name = localHost.getHostAddress();

        System.out.println(name);

 

getAddress()以网络字节顺序将IP地址作为一个字节数组返回

        InetAddress localHost = InetAddress.getLocalHost();

        byte[] name = localHost.getAddress();

        System.out.println(name[0]);

 

      InetAddress byName = InetAddress.getByName("www.baidu.com");
        System.out.println(byName);//www.baidu.com/115.239.211.112
        System.out.println(byName.getHostName());//www.baidu.com
        System.out.println(byName.getAddress());//[B@14ae5a5
        System.out.println(byName.getCanonicalHostName());//115.239.211.112
        System.out.println(byName.getHostAddress());//115.239.211.112

确定IP地址是IPv4还是IPv6:

地址类型 

Java提供了10个方法来测试InetAddress对象是否符合其中某个标准

 1、

2、

3、

 

4、

5、

 

 6、

 

 7、

 

 8、

 

 9、

 

 10、

 

原文地址:https://www.cnblogs.com/Mrchengs/p/10909271.html