域名和IP地址的转换工作是怎么进行的?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了域名和IP地址的转换工作是怎么进行的?相关的知识,希望对你有一定的参考价值。

利用Java完成域名和IP地址的转换
责任编辑:admin 更新日期:2005-8-6

利用Java完成域名和IP地址的转换

对我们普通用户而言,形象化的符号要比一捆枯燥的数字编码要好记得多。比如,我们会很容易地记住字符串“www.oscar.com”,却很难记住206.17.191.12。本文简要地介绍了Internet命名规则和地址的划分约定,然后介绍了如何利用Java语言完成符号名(上面的字符串)和IP地址(上面的数字串)之间的转换工作,并给出一个实例,检查可访问的远程主机。

· Internet命名规则和地址划分约定

在Internet上,符号名(symbolic Name)用来命名主机和网络,例如www.oscar.com。这些符号名的“学名”叫做“Domain Name”,即域名。虽然域名对我们来说方便得多,但在它们用作通信标识之前,必须转换为IP地址(Internet Protocol Address)。IP地址是一个32位的标识符,包括一个网络标识和主机标识,以便唯一地标识主机和网络。域名转换为IP地址的工作是由专门的系统完成,这就是域名系统(Domain Name SystemDNS)。

同一网络或不同网络主机之间进行数据的发送/接收时,IP地址就开始起作用了。如果是同一网络中主机之间的数据传递,则仅利用IP地址中的主机标识,来确定网络中主机的所在。另一方面,如果是不同网络中主机之间的通信,则要同时利用主机标识和网络标识来确定相应的主机。定位网络和主机,再进行数据传送的过程称为路由(routing)。网络中的路由器(router)包含一个IP层(IP Layer),它负责执行路由算法,将数据包发送到目的地。在Internet上,将数据库发送到目的地是IP层份内之事。

IP地址是Internet注册部门Network Information Center(网络信息中心NIC)分配给不同的组织,各组织再下放给多个部门。IP地址要占用4个字节。

经过路由的数据包,也有可能会在传送的过程中丢失。于是,人们就利用底层传输协议,来进行数据传送正确与否的判断。例如,TCP用于检查错误或数据丢失,并在出错时,再次发送相应的数据库,直至对方主机正确接收为止。

目前,共计有3类(或3个级别)的IP地址:A类、B类和C类。另外,还有一类IP地址叫作“Multicast”,在某些Internet主机上使用。这些不同类别的IP地址满足了不同组织的需要。例如,A类地址主要用于主机数目超过65536的大型网络系统;B类地址则用于中型网络系统,其主机数大于255,却小于65536;C类地址则用于那些主机数量小于256的小型网络。

不同类别地址的十进制表示如下,其中的十进制数代表允许的地址范围:

· A类

网络ID 主机ID
1~127 0~255 0~255 0~255

· B类

网络ID 主机ID
128~191 0~255 0~255 0~255

· C类

网络ID 主机ID
191~233 0~255 0~255 0~254
Multicast

· Multicast

191~233 0~255 0~255 0~254

数字0和255另有特殊的含意。数字0是为那些地址不明的主机保留的。某些情况下,如错误的系统配置,主机标识或网络标识不明的情况也会发生。例如,某个主机的C类地址为0.0.0.42,则说明其主机标识为42,而它所处网络的网络标识则是“未知数”0。
数字255则用于广播发送方式,即一台主机发出的信息会传送到网络中所有的主机上。

· 获得IP地址

为了获得所在网络的IP地址,或者网络中其他主机的IP地址,我们可以用java.net软件包中的java.net.InetAddress类加以实现。例如,如果我们希望得到所在网络的IP地址,我们可以调用InetAddress类中的getLocalHost()和getAddress()方法。getLocalHost()返回一个InetAddress对象;而getAddress()则返回一个长度为4的字节数组(IP地址为4个字节)。

如果要编制一个基于网络的应用程序,我们也许需要知道准备运行这个程序的主机的域名或IP地址。如果这个程序只在我们自己的主机上运行,而且我们也知道主机的域名或IP地址,则我们就可以这样进行:定义一个字符串常量即可,如:string localHost=“my-machine-name”。但大多情况下,我们编制

/*
* Program:sample1.java
*/
import java.net.*/;
public class GetName
public static void main (String argv〔〕) throws Exception
InetAddress host=null;
host=InetAddress.getLocalHost();
System.out.println(host.getHostName());


的程序将在不同的主机上运行,这样才有实用价值。那么,象上面那样,定义一个localHost常量的方法就不太好用了。我们希望应用程序能够自动检测得到当前主机的域名。下面的程序说明了如何完成这一工作。

InetAddress是java.net软件开发包中的一个“现成”的类。在上面的代码中,我们可以说,其中的变量host就是一个InetAddress;InetAddress.getLocalHost()返回一个InetAddress。例如,某个主机域名为“sample”,其IP地址为“128.118.2.10”,那么,InetAddress.getLocalHost()调用返回后,变量host的值就成了“sample/128.118.2.10”。如果只对其中的主机域名感兴趣,则可以调用getHostname()。
简单地说,IP地址是4个数字。为了得到数字形式的IP地址,我们可以将上面程序稍作改动。
/*
* Program:sample2.java
*/
import java.net.*;
public class GetAddress
public static void main (String argv〔〕) throws Exception
InetAddress host=null;
host=InetAddress.getLocalHost();
byte ip〔〕=host.getAddress();
for (int i=0;i<ip.length;i++)
if (i>0 System.out.print(".");
System.out.print(ip〔i〕& 0xff);

System.out.println();

getAddress()返回一个长度为4的字节数组。例如,如果IP地址为“128.118.2.10”,则上面程序中的变量ip的最后内容为:
ip〔0〕=128ip〔1〕=118ip〔2〕=2ip〔3〕=10
Internet上的所有计算机都拥有一个唯一的IP地址和主机名。既然如此,我们要这些地址有什么用呢这些地址可以帮助我们定位Internet上的固定资源,也可以使路由工作顺利地进行。
熟知UNIX的人都知道,UNIX系统中有一个复杂的DNS客户程序nslookup工具。利用nslookup,我们可以根据已知的IP地址,找到相应的主机名;也可以根据主机名,找到相应的IP地址。它可算是一个非常有用的工具。下面的示例程序则可以让我们找到Internet上所有可以访问主机的IP地址。
/*
* Program:nslookup.java
*/
import java.net.*/;
public class nslookup
//Usage:java nslookup hostname
public static void main (String argv〔〕) throws Exception
String host=argv〔0〕;
InetAddress address=null;
try
address=InetAddress.getByName(host);
catch(UnknownHostException e)
System.out.println("Unknown host");
System.exit(0);

byte〔〕 ip〔〕=address.getAddress();
for (int i=0;i<ip.length;i++)
if (i>0 System.out.print(".");
System.out.print(ip〔i〕& Oxff);

System.out.println();

在JDK 1.0.2(Java Develop Kit-Java开发工具包中,编制一个程序,将主机名转换为IP地址并不太容易。这是由于InetAddress类中getHostName方法中有一个bug。这个bug在JDK 1.1 beta版中得以修正,所以下列代码在JDK 1.1中应该可以运行。
参考技术A 通过dns即地址解析服务器

浅入DNS

1.DNS是怎么工作的

  首先我们可以很简单的理解DNS协议,它就是一个将域名与ip地址进行双向转换的协议,而消息类型只有查询和回应2种类型。那客户端查询域名,是要请求谁呢?答案是域名服务器,现在域名服务器分为以下4类,按照层次从上往下:

根域名服务器:最高层次最重要的域名服务器,它知道所有的顶级域名服务器的域名和ip地址,一般请求根域名服务器返回的是要请求的顶级域名服务器的ip地址。我们常常听说的13个域名服务器指的就是它,但根域名服务器绝不是由仅仅的13台服务器组成,而是一个域名服务器由多个主机组成,它们有相同的ip。现在基本上普通域名服务器都能就近找到一台根域名服务器,当本地域名服务器请求根域名服务器时,路由器就能找到离这个本地域名服务器最近的一个根域名服务器。

顶级域名服务器:它负责该顶级域名中所有注册的二级域名。比如.com顶级域名服务器里就存放了所有xxx.com域名和ip地址映射表。

权限域名服务器:这类服务器负责某一特定域名的域名解析,很多公司都有权限域名服务。比如腾讯有它的权限域名服务器,里面存储了腾讯域名和ip地址的映射关系。同时权限域名服务器也充当了本地域名服务器的角色,你可以将你的域名注册到腾讯的域名服务器中。

本地域名服务器:这台服务器的ip地址就是我们电脑里配置的dns,本地域名服务器一般离用户是比较近的,当本地主机无法解析域名就会给本地域名服务器发送请求。

现在知道请求的是域名服务器了,也知道了一共有哪几类域名服务器,接下来我画了张图来描述整个dns请求的流程,整个过程采用迭代查询。注意权限域名服务器一般是不会采用递归查询的,它会直接返回ip地址让请求着再去访问这个ip。

技术分享

 2.DNS数据格式

  dns固定首部为12字节,如下图所示。当请求本地域名服务器如果它已经缓存了这个域名所对应的ip地址,那么这个答案将会被标记为非权威的,只有权限域名服务器返回的数据包才会将这个包标记为权威的,这对应着固定首部中的权威答案数据。后2张表格是dns首部中的标志位数据和rCode的数据。随着dns的发展标志中的16位功能已经有点不够用了,因此现在有很多dns服务器运行EDNS(扩展DNS),原来回应数据如果超过512字节将会被丢弃进而可以转为tcp连接,EDNS则可以支持超过512字节的大数据包回应。

技术分享

 

QR 1位 查询时这位为0,回应则为1
Opcode 4位 定义查询或回应的类型,值为0表示是一个标准的查询/回应
AA 1位 在回应数据包中使用,值为1表示回应是一个权威回应。
TC 1位 当回应大于512字节时此标志位置1,最终数据长度会被删减为512字节,此时客户端可采用tcp来询问
RD 1位 客户端使用递归时此位会置1
RA 1位 只在回应数据包中设置,当为1时表示可采用递归回应
保留位 3位 全都设置为0
rCode 4位 仅在回应消息中有用,表示返回类型
rCode 错误类型
0 没有错误
1 格式错误
2 名称服务器错误
3 域参照错误
4 不支持的查询类型
5 不允许的动作

 

3.DNS的安全隐患

  目前对于DNS的安全隐患主要分为2类,一类是攻击真实的域名服务器让服务器掉线,比如利用服务器软件漏洞,曾经还发生过对根域名服务器的成功攻击。另一类是抓住dns协议的漏洞来进行攻击。dns协议很简单,就一个请求和回复,在这个过程中会对服务器返回结果的ip地址和首部中16位标识进行验证,如果ok那dns客户端总是相信服务器返回的结果是正确的。正是这个地方攻击者可以做手脚,比如DNS缓冲区中毒攻击,它需要攻击者能够看到dns服务器的查询数据包,有了查询数据攻击者才能伪造回应信息给dns服务器。它的原理是攻击者替换dns服务器中的多行数据从而导致客户端收到错误的ip地址,然后去访问攻击者想要客户端访问的网站。现在关键是攻击者如何才能将恶意数据放入dns服务器中呢?可以想象攻击者要么获得对服务器的访问,要么向发送请求的dns服务器回应错误的信息,以达到伪造的目的。对于这种攻击可以采用dns数据加密的方式。还有一种攻击类似于syn flood,假设攻击者给很多服务器发送大量请求报文,这可能造成网络的流量猛增而瘫痪。不过dns是采用无连接的udp,当udp缓冲区被塞满时将会丢弃多余的数据包,而dns客户端请求不到ip地址将会重试几次请求或者用户重新在浏览器点击链接。因此这种攻击只要采用防火墙进行过滤网络就会快速恢复。

以上是关于域名和IP地址的转换工作是怎么进行的?的主要内容,如果未能解决你的问题,请参考以下文章

DNS工作原理

浅入DNS

怎么把自己的ip地址转换成其他地方的

请问域名导向怎么做(请说明具体步骤)

C#程序怎么获得外网IP和内网IP?

DNS域名解析