实验2 主机域名和IP地址的解析

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验二、主机(域)名和 IP 地址解析

实验目的及要求:掌握主机(域)名和IP地址相互转换的工作原理,

学会使用Winsock提供的相关函数编制程序。

实验方法:1. 阅读文档,熟悉主机(域)名和IP地址解析工作原理;

2. 参考本实验后附录的关键功能的程序示例,使用

Visual C++ 输入编辑、编译、运行与调试解析程序;

3. 在命令行状态下测试本机主机名和IP地址是否解析

正确,测试附录中表里所列信息是否正确,并记录一些

常用门户网站的域名及对应的IP地址。

实验内容:(1)写出编写的 Visual C++域名和地址解析源程序如下:

(2)运行、测试域名地址解析程序,记录测试结果,分析遇到的问题与解决的办法。

(3)记录 5个常用门户网站的域名及对应的 IP 地址。

编程背景材料:

1.基本概念

(1)主机(域)名->IP地址解析

Winsock 应用程序如要通过 TCP/IP 网络和另一台主机通信时,必须知道那个主机的IP 地址。依用户看来, IP 地址是不容易记的。在指定机器时,许多人更愿意利用一个易记的、友好的主机名而不是 IP 地址。Winsock 提供了两个支持函数,它们有助于用户把一个主机名解析成 IP 地址。

Windows 套接字API函数 gethostbyname() 和 WSAAsynGetHostByName() 从主机数据库中取回与指定的主机名对应的主机信息。两个函数均返回一个 HOSTENT 结构,在winsock2.h 里该 HOSTENT 结构的格式声明如下:

struct hostent {

char FAR * h_name; /* official name of host */

char FAR * FAR * h_aliases; /* alias list */

short h_addrtype; /* host address type */

short h_length; /* length of address */

char FAR * FAR * h_addr_list; /* list of addresses */

#define h_addr h_addr_list[0] /* address, for backward compat */

};

并由此定义了指向该结构的指针LPHOSTENT:

typedef struct hostent FAR * LPHOSTENT;

h_name 字段是正式的主机名。如果解析名字时使用域名系统 DNS,它就是使域名服务器返回响应的“全限定域名”(FQDN)。如果解析名字时按本机系统目录中的 hosts 文件来解析,主机名就是该文件中对应 IP 地址行后跟的第一个主机名。 h_aliases 字段是一个由若干个主机别名组成的空中止字符串数组。 h_addrtype 表示即将返回的地址家族类型。h_length 字段则对 h_addr_list 字段中的每一个地址的字节长度进行定义。

h_addr_list 字段是一个由若干个主机 IP 地址组成的空中止数组(因为可以为一台主机分配若干个 IP 地址),这个数组中的每个地址都是按网络字节顺序返回的。一般情况下,应用程序都采用该数组中的第一个 IP 地址。但是,如果返回的地址不止一个,应用程序就会相应地选择一个最恰当的,而不是一直都用第一个地址。可以使用inet_ntoa() 函数将网络字节顺序的地址转换到以‘.’分隔的十进制字符串形式。

===================================================================== 说明(1) : “主机字节顺序”与“网络字节顺序”

如将四字节的IP地址“1.2.3.4”(MSB=1, LSB=4)写成一个unsigned long 型的长字时,字节顺序的排法有两种:一种是Intel X86 主机内存中的排法,叫“主机字节顺序”,最低有效字节LSB在前,最高有效字节MSB在后,字节顺序为0x04,0x03,0x02,0x01;另一种是“网络字节顺序”,这是互联网联网标准指定

使用的多字节顺序排法,它规定,最高有效字节MSB在前,最低有效字节LSB在后,因此,上例的字节顺序排成0x01,0x02,0x03,0x04. 在网络套接字程序编写时,涉及到主机中的多字节数据,该数据内各字节排列一般用“主机字节顺序”,凡涉及到网络发送、接收的数据结构中,其多字节数据中各字节排列一般用“网络字节顺序”,这在我们编写网络套接字程序时是要时时当心的。

下面两个API函数将一个数从“主机字节顺序”转换成“网络字节顺序”:

u_long htonl(u_long hostlong);

u_short htons(u_short hostshort);

下面两个API函数将一个数从“网络字节顺序”转换成“主机字节顺序”:

u_long ntohl(u_long netlong);

u_short ntohs(u_short netshort);

说明(2) : inet_ntoa( ) 函数与 inet_addr( ) 函数

inet_ntoa() 函数将网络字节顺序的地址转换到以‘.’分隔的十进制字符串形式,它在 winsock2.h 中定义和涉及的参数结构如下:

char FAR * WSAAPI inet_ntoa(struct in_addr in);

其中,入口参数为结构 in_addr 类型,该类型在 winsock2.h 中定义如下:

struct in_addr {

union {

struct { u_char s_b1, s_b2, s_b3, s_b4; } S_un_b;

struct { u_short s_w1, s_w2; } S_un_w;

u_long S_addr; //我们常常用该联合中的这个成员定义, 该长字就是按网 } S_un; //络字节顺序排列的

}

另一个函数 inet_addr() 的作用与函数 inet_ntoa() 刚好相反,它把以‘.’分隔的十进制字符串形式表示的IP地址转换成网络字节顺序的 u_long 地址。也即:

“1.2.3.4”---> 0x01,0x02,0x03,0x04 (即无符号长字 0x04030201), 用inet_addr()

0x01,0x02,0x03,0x04 (即无符号长字 0x04030201) ----> “1.2.3.4”, 用inet_ntoa()

从主机名解析IP地址所用的gethostbyname() API 函数原型定义如下:

struct hostent FAR * gethostbyname (const char FAR * name);

如果这个函数调用成功,系统就会返回一个指向HOSTENT 结构的指针。注意,保存HOSTENT 结构的是系统内存,该内存由系统来维护,应用程序不需维护它的状态。因此,在应用程序中用过后不必释放这个已返回的结构。

WSAAsyncGetHostByName API 函数是gethostbyname 函数的异步版,后一个函数在结束时,利用Windows 消息向应用程序发出通知。在此我们不对此函数作详细解释。

在使用时,我们需要将LPHOSTENT 所指向的结构HOSTENT 的成员h_addr_list 的指针转换成in_addr 类型的指针LPIN_ADDR 来作为inet_ntoa 函数的参数。LPIN_ADDR 定义如下:

typedef struct in_addr FAR *LPIN_ADDR;

SOCKADDR_IN 结构来指定IP 地址和服务端口信息,该结构的格式如下:

相关文档
最新文档