曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 5211|回复: 1
打印 上一主题 下一主题

gethostbyname() -- 由主机名获取主机信息

[复制链接]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
跳转到指定楼层
楼主
发表于 2010-5-6 20:55:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
函数原型
#include <netdb.h>
struct hostent *gethostbyname(const char *name);
其中,参数 name 为主机名。该函数返回一个struct hostent 的结构体指针,这个结构体定义如下:
struct hostent {
               char  *h_name;            /* official name of host 主机的官方名*/
               char **h_aliases;         /* alias list 主机备选名称,以NULL结尾的列表*/
               int    h_addrtype;        /* host address type 返回的地址类型,只能是 AF_INET 或 AF_INET6 两种类型*/
               int    h_length;          /* length of address 地址长度(以字节为单位)*/
               char **h_addr_list;       /* list of addresses (主机的网络地址的指针数组,以NULL结尾的列表)*/
}

示例
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

extern int h_errno;

int main (int argc, char **argv)
{
        int i;
        struct hostent *hostp;

        if (argc < 2) {
                printf ("Usage: ./gethostbyname host_name\n");
                exit (1);
        }

        if ((hostp = gethostbyname (argv[1])) == NULL) {
                fprintf (stderr, "%s : host '%s'\n", hstrerror (h_errno), argv[1]);
        exit (1);
        }
        printf ("要查询的主机 %s 的信息为:\n", argv[1]);
        printf ("主机的官方名:%s\n", hostp->h_name);

        printf ("主机的备选名称为:\n");
        /*一个主机可能有多个备选名称*/
        for (i = 0; hostp->h_aliases[i]; i++)
                fprintf (stdout, "主机备选名称%d:%s\n", i, hostp->h_aliases[i]);

        printf ("地址类型: %s\n", hostp->h_addrtype == AF_INET? "AF_INET":"AF_INET6");

        if (hostp->h_addrtype == AF_INET) {
                for (i = 0; hostp->h_addr_list[i]; ++i)
                        printf ("IP地址: %s\n", inet_ntoa (*(struct in_addr*)hostp->h_addr_list[i]));
        }

        return (0);
}
运行与输出
./gethostbyname www.sina.com
要查询的主机 www.sina.com 的信息为:
主机的官方名:ara.sina.com.cn
主机的备选名称为:
主机备选名称0:www.sina.com
主机备选名称1:us.sina.com.cn
主机备选名称2:news.sina.com.cn
主机备选名称3:jupiter.sina.com.cn
地址类型: AF_INET
IP地址: 58.63.236.46
IP地址: 58.63.236.47
IP地址: 58.63.236.48
IP地址: 58.63.236.49
IP地址: 58.63.236.50
IP地址: 58.63.236.26
IP地址: 58.63.236.27
IP地址: 58.63.236.28
IP地址: 58.63.236.29
IP地址: 58.63.236.30
IP地址: 58.63.236.31
IP地址: 58.63.236.32
IP地址: 58.63.236.42
IP地址: 58.63.236.43
IP地址: 58.63.236.44
IP地址: 58.63.236.45

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
沙发
 楼主| 发表于 2012-6-8 11:17:46 | 只看该作者

什么是规范名?

在上面的程序输出中所说的“官方名”也称为“规范名”,即通常所说的“别名” (CNAME)  。

比如 DNS 中有下面的条记录:
NAME                    TYPE   VALUE
--------------------------------------------------
foo.example.com.        CNAME  bar.example.com.
bar.example.com.        A      192.0.2.23
正如上面所示,如果一个用户访问的是 foo.example.com ,那么在进行 DNS 查询时,解析器会去查找它的别名记录,即 bar.example.com ,由于最终要得到的是一个域名的 IP,因此会接着查看 bar.example.com 的 A 记录,此时得到 IP 地址 192.0.2.23,并将该地址返回。

比如我有一个网站 www.wentowns.com,访问得到:

我还在我的 DNS 控制面板里有如下设置:

上面,我设置了 admin, ftp, upload 这几个主机记录的 CNAME 为 www.mywentowns.com ,因此我不论是访问 admin.wentowns.com,ftp.wentowns.com 还是 upload.wentowns.com 都会定向到 www.mywentowns.com 这里,如:


在实际的应用中,CNAME 应用在 CDN 加速服务中会比较多。CDN 加速是利用多节点加速网站访问速度,缓解主服务器负载的一种服务。比如使用 webluker 的 CDN 服务,那么它会要求你设置 CNAME 如下:

这时,你只需要在你的 DNS 控制面板那里添加一条上面所要求的 CNAME 即可。

查询 DNS 信息的常用命令是 dig ,比如我来查询一下百度的 DNS 信息:
# dig www.baidu.com

; <<>> DiG 9.7.0-P1 <<>> www.baidu.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15142
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;www.baidu.com.            IN    A

;; ANSWER SECTION:
www.baidu.com.        90    IN    CNAME    www.a.shifen.com.
www.a.shifen.com.    136    IN    A    220.181.111.148
www.a.shifen.com.    136    IN    A    220.181.112.143

;; Query time: 16 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Thu Jun  7 23:03:00 2012
;; MSG SIZE  rcvd: 90
可见 www.baidu.com 的 CNAME 记录是 www.a.shifen.com ,你可以 ping 一下百度的域名,也可以看到:

C:\\Users\\Administrator>ping www.baidu.com

正在 Ping www.a.shifen.com [220.181.111.148] 具有 32 字节的数据:
来自 220.181.111.148 的回复: 字节=32 时间=37ms TTL=54
来自 220.181.111.148 的回复: 字节=32 时间=37ms TTL=54
来自 220.181.111.148 的回复: 字节=32 时间=36ms TTL=54
来自 220.181.111.148 的回复: 字节=32 时间=37ms TTL=54

220.181.111.148 的 Ping 统计信息:
    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 36ms,最长 = 37ms,平均 = 36ms

下面返回上面的程序,同样可以用来测试百度:
# ./gethostbyname www.baidu.com
要查询的主机 www.baidu.com 的信息为:
主机的官方名:www.a.shifen.com
主机的备选名称为:
主机备选名称0:www.baidu.com
地址类型: AF_INET
IP地址: 220.181.112.143
IP地址: 220.181.111.148

再考察另一个例子。拿我们网站的友情链接里的“墨宝阁”做下实验,它是个小说网站,服务器放在海外,为了加速访问速度,也用了 webluker 的 CDN 服务(不是在打广告,如果你的网站没有备案,是论坛的话,它是不会让你使用的)。

先用上面的程序来观察一下输出情况:
# ./gethostbyname www.mobaoge.net
要查询的主机 www.mobaoge.net 的信息为:
主机的官方名:common.xgslb.net
主机的备选名称为:
主机备选名称0:www.mobaoge.net
主机备选名称1:www.mobaoge.net.xgslb.net
地址类型: AF_INET
IP地址: 218.75.30.22
IP地址: 113.107.43.238
再用 dig 命令来比对一番:
# dig www.mobaoge.net

; <<>> DiG 9.7.0-P1 <<>> www.mobaoge.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20514
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;www.mobaoge.net.        IN    A

;; ANSWER SECTION:
www.mobaoge.net.    27    IN    CNAME    www.mobaoge.net.xgslb.net.
www.mobaoge.net.xgslb.net. 13    IN    CNAME    common.xgslb.net.
common.xgslb.net.    461    IN    A    218.75.30.22
common.xgslb.net.    461    IN    A    59.57.12.38

;; Query time: 6 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Thu Jun  7 23:10:31 2012
;; MSG SIZE  rcvd: 122
从两个输出中,容易知道 [color=#aa22ff ]struct [color=#000000 ]hostent 结构中的成员 h_name 是怎么一回事了。另外还注意到输出的两个主机名,即  [color=#aa22ff ]struct hostent 结构中的 h_addr_list 成员,此时它列出了两个名称:www.mobaoge.net 和 www.mobaoge.net.xgslb.net ,从 dig 的输出里可以知道:当你访问 www.mobaoge.net 时,DNS 服务器解析器会去查找别名 www.mobaoge.net.xgslb.net ,接着又找到 common.xgslb.net ,最后返回 A 记录,要么是 218.75.30.22,要么是 59.57.12.38 。使用 ping 命令也可以类似检测:
C:\\Users\\Administrator>ping www.mobaoge.net

正在 Ping common.xgslb.net [59.57.12.38] 具有 32 字节的数据:
来自 59.57.12.38 的回复: 字节=32 时间=26ms TTL=55
来自 59.57.12.38 的回复: 字节=32 时间=26ms TTL=55
来自 59.57.12.38 的回复: 字节=32 时间=25ms TTL=55
来自 59.57.12.38 的回复: 字节=32 时间=26ms TTL=55

59.57.12.38 的 Ping 统计信息:
    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 25ms,最长 = 26ms,平均 = 25ms

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-9 11:43 , Processed in 0.063364 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表