网络编程-Java中的Internet查询
前提在深入理解URL、URI等概念,或者学些Socket相关的知识之,有必要系统理解一下Internet相关的一些基础知识。 Internet地址连接到Internet(因特网)的设备称为节点(node),而任意一个计算机节点称为主机(host)。每个节点或者主机都由至少一个唯一的数来标识,这称为Internet地址或者IP地址。 IP和域名如果使用Java作为开发语言的话,不需要担心IP或者域名的工作原理,但是我们需要理解IP寻址的一些基础知识。我们目前常用的网络都是IPv4网络,每个计算机节点都是由一个4字节(32bit)的数字标识,这个数字标识的格式是点分四段(dotted quad,形式是:xxx.xxx.xx.xx),其中的每个数字都是一个无符号字节,取值范围是0到255。当数据通过网络传输的时候,数据包的首部中要包括要发往的机器地址(目的地址)和发送这个数据包的机器地址(源地址)。 可以使用的IPv4类型的IP地址总量大概是40亿多一点,因此无法做到地球上每个人都分配一个唯一的IPv4的IP地址,所以IPv6就诞生了,目前网络由IPv4向IPv6过度(不过这个过度过程相对缓慢,因素很多)。IPv6网络中的IP地址使用16字节(128bit)的数字标识。IPv6地址的表示形式通常是以英文冒号分隔的8个区域,每个区域都是4个十六进制的数字,举个例子:FEDC:BA98:7654:3210:FEDC:BA98:7654:3210就是一个合法的IPV6地址。而在IPv4和IPv6的混合网络中,IPv6地址的最后四个字节有时候表示形式为IPv4地址的点分四段地址。IPv6地址只在Jdk1.4以及之后的版本支持,换言之,Jdk1.3或者之前的版本只能使用IPv4地址。 虽然计算机可以轻松地处理数字,但是人脑的记忆对于数字并不敏感,因此开发了域名系统(Domain Name System,也就是DNS),用于将人脑易于记忆的主机名(如www.baidu.com)转换为数字Internet地址(如183.232.231.173)。这里不展开DNS的具体内容,作为开发者,我们可以简单理解为它就是一个巨型分布式数据库,用于映射主机名(域名)和IP地址,画个图大致如下: 端口因为每台计算机都不是只做一件事,相当于计算机做的每一种业务逻辑需要从逻辑上隔离,例如FTP请求的处理要和电子邮件的处理分离,FTP请求处理也要和Web业务处理分离,所以每种业务逻辑的处理需要使用一个逻辑分离的标识,这个标识就是端口(port)。一般每台计算机有成千上万个逻辑端口(确切来说,每个传输层协议都有65535个端口,Windows系统中,11023号端口是系统端口,用户无法修改,102465534端口是系统为用户预留的端口,而65535号端口为系统保留端口),每个端口可以分配给一个特定的服务。例如Web的底层协议Http协议通讯一般使用80端口,使用浏览器URL访问服务器的80端口可以省略URL中的端口号。 Java对网络的抽象InetAddress单词InetAddress是Internet Address的缩写合并,代表因特网地址。java.net.InetAddress类是Java对IP地址(包括IPv4和IPv6地址)的高度抽象表示。大多数网络编程相关的类都会用到InetAddress,如Socket、ServerSocket等,InetAddress两个最核心的属性是主机名(host)和IP地址,对应属性hostName和address。 创建InetAddress实例创建InetAddress实例主要依赖它的工厂方法(实际上InetAddress的构造函数是包私有的,也就是无法通过new关键字创建实例),比较常用的一个静态工厂方法是:
其中参数可以为主机名(域名)或者点分四段地址,前者相当于通过主机名查找一个可连接的IP地址,后者相当于通过IP地址反查主机名,值得注意的是,这个方法调用的使用会建立与本地DNS服务器的连接进行主机名或者数字地址查找,如果DNS服务器找不到主机或者地址,会抛出UnknownHostException异常。
InetAddress覆写了
有些时候,我们知道数字IP地址,就可以由数字地址直接创建一个InetAddress实例,这样就可以不必使用
这两个方法可以创建主机名不存在或者主机名无法解析的InetAddress实例。举个例子:
实际上,域名www.doge.com并不存在,但是这个方法并不会抛出异常。 如果要查询一个主机名的所有IP地址,可以使用:
如果需要查询本机的主机名和IP地址,可以使用:
注意这个方法会尝试连接DNS去查询本地计算机的真正的主机名和IP地址,如果查询失败,它就会返回回送地址,也就是主机名是"localhost",IP地址是点分四段地址"127.0.0.1"。 InetAddress缓存DNS查找的开销可能相当大(如果请求需要经过多个中间服务器或者尝试解析一个不可达的主机,可能需要耗费几秒的时间),所以InetAddress会缓存DNS查询结果,也就是一旦得到一个给定主机的地址,就不会再次查找,即使为同一个主机创建多个InetAddress实例,也不会再次进行DNS查询。这样的缓存机制对于性能来说是有好处的,但是也会带来负面影响:
因此,Java对于不成功的DNS查询结果仅仅缓存10秒,而且可以通过下面两个系统变量控制缓存的时间:
InetAddress提供的基本属性获取方法InetAddress提供四个基本属性获取方法,用于获取当前InetAddress表示的主机名和IP地址。
注意上面的几个方法只有Getter,没有Setter方法,说明这几个属性的设置权限是java.net包中的类库。
上面的 InetAddress提供的地址类型判断方法有些IP地址和地址模式有特殊的含义,例如127.0.0.1是本地回送地址,244.0.0.0到239.255.255.255范围内的IPv4地址是组播地址。InetAddress中提供10个公有实例方法来判断InetAddress对象是否符合这些地址模式:
|
- 阶段1 语言基础+高级_1-3-Java语言高级_08-JDK8新特性_第1节
- java编程进行动态编译加载代码分享
- 使用Java在MongoDB中查询数组元素上的文档
- 添加另一个对象时java.util.ConcurrentModificationExcepti
- spring boot实战教程之shiro session过期时间详解
- 什么是贫血模型,什么是充血模型?为什么我们会强制要求使用
- java – 我可以在Spring Web应用程序的上下文中打开REPL吗?
- java8在Collection中新增加的方法removeIf
- Spring Boot 使用Druid详解
- For循环在java中永远运行[复制]