`
yesjavame
  • 浏览: 694836 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

一段代码备忘,放在这里,我以前好象没有发表过,CN-JAVA竟然有人原文COPY了说是他的原创.发个修改版的.

阅读更多
/**//*
*DNSTools.java
*
*Createdon2003-9-24,13:56:09
*
*Tochangethistemplate,chooseTools|Templates
*andopenthetemplateintheeditor.
*/


packagetest;

/***//**
*
*
@authoraxman
*/

importjava.io.*;
importjava.net.*;
importjava.util.*;

publicclassDNSTools...{


publicstaticfinalbyteTYPE_A=1;//A记录
publicstaticfinalbyteTYPE_CNAME=5;//CNAME记录
publicstaticfinalbyteTYPE_MX=15;//X记录

privatestaticintPORT=53;//DNS服务的端口
publicstaticString[]getQueryRecords(StringNameServer,StringdomainName,bytetype)...{

byte[]buf=newbyte[512];
makeQueryData(buf,domainName,type);
//封装DNS请求

//以下获取DNS服务器的响应内容
DatagramSocketudpSocket=null;
try...{
InetAddressdnsIP
=InetAddress.getByName(NameServer);
DatagramPacketsendPack
=newDatagramPacket(buf,buf.length,dnsIP,PORT);
udpSocket
=newDatagramSocket(PORT);
udpSocket.send(sendPack);
DatagramPacketreceivePack
=newDatagramPacket(buf,buf.length);
udpSocket.receive(receivePack);
buf
=receivePack.getData();
}
catch(Exceptione)...{
returnnull;
}

finally...{try...{if(udpSocket!=null&&!udpSocket.isClosed())udpSocket.close();}catch(Exceptione)...{}}

//以下对DNS响应内容做分析

intqCount=((buf[4]&0xff)<<8)|(buf[5]&0xFF);//获得请求数
if(qCount<0)returnnull;
intaCount=((buf[6]&0xff)<<8)|(buf[7]&0xff);//获得响应数
if(aCount<0)returnnull;
intposition=12;//起始位置

for(inti=0;i<qCount;i++)...{
StringBufferdmBuffer
=newStringBuffer();
position
=analyzer(buf,dmBuffer,position);
position
+=4;//增加长度字节部分
}

ArrayList
<String>al=newArrayList<String>();
for(inti=0;i<aCount;i++)...{
StringBufferdmBuffer
=newStringBuffer();
position
=analyzer(buf,dmBuffer,position);
position
+=10;
intpref=(buf[position++]<<8)|(buf[position++]&0xff);//获得基数
dmBuffer=newStringBuffer();
dmBuffer.append(pref).append(
"");
position
=analyzer(buf,dmBuffer,position);
al.add(dmBuffer.toString());
}

returnal.toArray(newString[al.size()]);
}



privatestaticintanalyzer(byte[]receiveBytes,StringBufferdmBuffer,intposition)...{
intlen=receiveBytes[position++]&0xff;//取得将要处理的部分的长度
if(len==0)...{
returnposition;
}

intoffset;//偏移
do...{
if((len&0xc0)==0xc0)...{//压缩格式
if(position>=receiveBytes.length)...{//超过包的大小
return-1;
}

offset
=((len&0x3f)<<8)|(receiveBytes[position++]&0xff);
analyzer(receiveBytes,dmBuffer,offset);
//再一次递归调用获得压缩前的名称
returnposition;
}
else...{//非压缩格式
if((position+len)>receiveBytes.length)...{//超过长度
return-1;
}

dmBuffer.append(
newString(receiveBytes,position,len));
position
+=len;
}


if(position>receiveBytes.length)...{
return-1;
}

len
=receiveBytes[position++]&0xff;
if(len!=0)...{
dmBuffer.append(
".");//加上.构成完整域名
}

}
while(len!=0);
returnposition;
}



privatestaticvoidmakeQueryData(byte[]sendBytes,StringdomainName,bytetype)...{
intid=137*(newjava.util.Random()).nextInt(65535);
sendBytes[
0]=(byte)(id>>8);
sendBytes[
1]=(byte)(id&0xff);
sendBytes[
2]=(byte)1;
sendBytes[
3]=(byte)0;
sendBytes[
4]=(byte)0;
sendBytes[
5]=(byte)1;
sendBytes[
6]=(byte)0;
sendBytes[
7]=(byte)0;
sendBytes[
8]=(byte)0;
sendBytes[
9]=(byte)0;
sendBytes[
10]=(byte)0;
sendBytes[
11]=(byte)0;
String[]cols
=domainName.split("\\.");
intposition=12;
for(inti=0;i<cols.length;i++)...{
sendBytes[position
++]=(byte)(cols[i].length()&0xFF);//转换为字节
byte[]b=cols[i].getBytes();
for(intj=0;j<b.length;j++)...{
sendBytes[position
++]=b[j];
}

}

sendBytes[position
++]=(byte)0;
sendBytes[position
++]=(byte)0;
sendBytes[position
++]=type;
sendBytes[position
++]=(byte)0;
sendBytes[position
++]=(byte)1;
}


publicstaticvoidmain(String[]args)throwsException...{
String[]s
=DNSTools.getQueryRecords("202.106.0.20","sina.com.cn",DNSTools.TYPE_MX);
for(inti=0;i<s.length;i++)
System.out.println(s[i]);
}

}


/**
| 2字节的标识 | 2字节的标志 | 2字节的请求个数 | 2字节的资源记录数 | 2字节的授权资源记录个数
| 2字节额外的资源记录数 | 查询的域名(不固定长度) | 针对请求的应答资源记录(长度不固定)
| 授权资源记录(长度不固定) | 额外记录信息(长度不固定)

标识字段用于指出报文的编号,一般由客户指定,DNS服务器返回信息时带上此标识,告诉客户端回答
的是哪一个请求。

标志字段的16比特划分为8个子字段,从左至右(高位到低位)分别为:
QR 1 bit :0 查询报文 1 响应报文
Opcode 4 bit :通常为0,表示标准查询 ,1 反向查询,2 服务器状态查询
AA 1 bit :用于服务器返回报文,表示是否是授权回答
TC 1 bit :由于UDP自身长度限制,往往会截断512字节后的内容,该位表示是否可截断
RD 1 bit :该为用于在查询报文中设置,并由服务器响应报文中返回。该位告诉服务器必须处理此查询,
如果该位为0,且服务器返回的授权回答个数为0,那么服务器必须返回一个能够解答该查询的其他服务器的列表
RA 1 bit :如果服务器支持递归,那么服务器在响应报文中设定该位。

随后的3bit必须为0

rcode 4 bit :最后为返回码,0 无差错,3 名字差错,即在服务器上不存在要查询的域名的记录,一般用于从最终的授权名
字服务器返回。


查询请求部分由查询名字 查询类型 查询类组成。查询名字由多个标识符的序列组成,每一个标识首字节说明该标识符的长度,
最终由字节0表示名字结束。譬如cn.yahoo.com由2 c n 5 y a h o o 3 c o m 0组成。如果此域名后面还用到,一般在后面采用
压缩格式,那么首字节不是长度了,而是一个最高位为1的字节,一般是0xc0,因为不会出现长度超过64的标识符。压缩格式的
标志字节后是该域名的原标识的偏移值。查询类型为2字节,1 表示A记录查询 5 表示CNAME记录查询 15 表示MX记录查询。类表
示是否是Internet数据。

应答报文中的应答记录由域名(长度不固定) 类型(2字节) 类(2字节) 生存时间(4字节,秒数) 资源数据长度(2字节)
资源数据(不固定)。域名的格式同查询域名格式相同。类型、类的解释同查询请求部分。资源数据根据记录类型不同而不同。

*/

分享到:
评论

相关推荐

    备忘录模式-极客学院-java-课件代码

    在"备忘录模式-极客学院-java-课件代码"这个压缩包中,我们可以期待找到相关的Java代码示例,这些示例可能包括发起人、备忘录和管理者类的实现,以及如何在实际场景中运用备忘录模式的示例。通过学习这些代码,...

    备忘录日程管理java代码

    本项目名为"备忘录日程管理java代码",它是一个基于Java的软件,主要功能集中在帮助用户进行备忘录记录和日程管理。下面我们将深入探讨这个项目涉及到的关键知识点。 1. **Java基础**: - **面向对象编程**:Java...

    备忘录JAVA代码

    【标题】"备忘录JAVA代码"涉及到的核心知识点主要集中在Java编程语言以及备忘录功能的实现上。Java是一种广泛使用的面向对象的编程语言,它以其"一次编写,到处运行"的特性闻名,具备强大的跨平台能力。在这个项目中...

    java设计模式-备忘录模式源代码

    备忘录模式是一种在软件工程中广泛使用的面向对象设计模式,它主要用来安全地保存对象的状态,以便在需要时能够恢复到先前的状态。这个模式的名字来源于我们日常生活中使用的备忘录,它记录了一些重要的信息,当需要...

    java课设--个人备忘录管理系统.doc.doc

    本系统是一个基于Java的个人备忘录管理系统,旨在提供一个方便、实用的个人信息管理平台,帮助用户更好地管理日常生活和工作中的信息。 系统需求分析 在现代信息社会中,人们越来越重视信息的交流和沟通,更加注重...

    计算机后端-Java-图解java设计模式代码.zip

    Java设计模式是软件开发中的重要概念,它是一种在特定情境下解决问题的经验总结,可以提高代码的可读性、可维护性和可复用性。在这个"计算机后端-Java-图解java设计模式代码.zip"压缩包中,我们很可能会找到各种Java...

    日历备忘录Java源码

    在本项目中,"日历备忘录Java源码" 提供了一套完整的日历应用程序的源代码,主要由四个核心文件组成:NotePad.java、CalendarPad.java、Month.java 和 Year.java。这些文件分别代表了备忘录、日历、月份和年份的功能...

    代码备忘录(经典的代码备忘录)

    2. **多语言支持**:作为一个全面的工具,代码备忘录通常支持多种编程语言,如Java、Python、C++等,这意味着无论你使用哪种语言进行开发,都能找到合适的存储空间。 3. **快速搜索**:强大的搜索功能是其一大亮点...

    javaMD5加密及登录验证(备忘) - Hibernate - Java - ITeye论坛.mht

    javaMD5加密及登录验证(备忘) - Hibernate - Java - ITeye论坛.mhtjavaMD5加密及登录验证(备忘) - Hibernate - Java - ITeye论坛.mhtjavaMD5加密及登录验证(备忘

    java实现备忘时钟

    在本文中,我们将深入探讨如何使用Java编程语言来实现一个备忘时钟应用程序。这个项目非常适合初学者,因为它涵盖了基础的Java编程概念,如时间处理、事件监听和用户界面设计。我们将逐步解析实现这样一个功能所需的...

    Android代码-备忘录源码.zip

    这个名为"Android代码-备忘录源码.zip"的压缩包文件很可能包含了一个完整的备忘录应用的源代码,这为我们深入学习Android开发提供了一个很好的实例。以下是基于这个描述可能涵盖的一些关键知识点: 1. **Android ...

    Java日历及备忘录

    Java日历及备忘录程序是一个实用的桌面应用程序,它模仿了Windows操作系统中的日历功能,并添加了备忘录管理特性。这个程序的核心是利用Java编程语言实现的,旨在帮助用户方便地查看日期并设置提醒,提高个人或工作...

    Java设计模式-备忘录

    在Java中,发起人通常会有一个私有的内部类来表示备忘录,这样可以确保备忘录只包含发起人关心的状态信息,避免了信息泄漏。 2. **备忘录(Memento)**:备忘录对象存储发起人的状态。它持有发起人需要保存的所有...

    java记事簿管理系统_备忘录管理系统_通讯录_记账本-源码+数据库+论文or文档.zip

    该压缩包文件“java记事簿管理系统_备忘录管理系统_通讯录_记账本-源码+数据库+论文or文档.zip”包含了基于Java开发的一个综合性的管理系统的源代码、数据库文件以及相关的论文或文档。这个系统集成了多个实用功能...

    java课设--个人备忘录管理系统

    在本项目中,"java课设--个人备忘录管理系统"是一个基于Java编程语言实现的课程设计项目,旨在提供一个方便用户记录、管理和检索个人备忘录的应用程序。这个系统通常包括用户界面、数据存储、备忘录的增删改查等功能...

    java开发备忘录

    Java开发备忘录是程序员在进行Java编程时的重要参考资料,它涵盖了从基础知识到高级特性的全方位内容。以下是一些关键的Java开发知识点,基于提供的信息,我们无法获取具体子文件的详细内容,所以将根据Java的常规...

    java课设--个人备忘录管理系统.doc

    Java 课设 - 个人备忘录管理系统 本系统是基于 Java 语言开发的个人备忘录管理系统,旨在提供一个简洁易用的个人信息管理平台。下面是该系统的详细知识点: 系统需求分析 在现代信息社会里,人们越来越重视信息的...

    java面试——深圳-乐信-Java高级.zip

    在Java高级面试中,面试官通常会关注候选人在核心Java、多线程、集合框架、JVM内存管理、设计模式、数据库操作、网络编程、异常处理、IO流、Spring框架及其实现原理等方面的知识掌握程度。以下是根据这些关键点展开...

    JAVA课设--个人备忘录管理系统.doc

    JAVA课设--个人备忘录管理系统

    java备忘录

    Java备忘录是一款基于Java编程语言开发的简单应用程序,它主要功能是对数据进行增、删、改、查操作。在这款应用中,开发者选择使用了HashMap作为核心数据结构来存储和管理数据。HashMap是Java集合框架中的一员,属于...

Global site tag (gtag.js) - Google Analytics