第九章基本名字和地址转换
FQDN:(Fully Qualified Domain Name)完全合格域名/全称域名,是指主机名加上全路径,全路径中列出了序列中所有域成员。全域名可以从逻辑上准确地表示出主机在什么地方,也可以说全域名是主机名的一种完全表示形式。从全域名中包含的信息可以看出主机在域名树中的位置。全域名在实际中是非常有用的。电子邮件就使用全域名作为收信人的电子邮件地址,如janicejones@ acmecompany. com,其中收信人为janicejones,跟在收信人名字后面是符号@,@后面是邮件服务器的全域名,或者说是邮件服务器所在企业的域名,最后是顶层域名.com。. com意味着acmecompany是一个商业机构
DNS中的条目称为资源记录RR,有如下几类RR
A 将主机名映射成32位ipv4地址。A(代表32位)
AAAA 将主机名映射成128位ipv6地址。AAAA(4*32=128位)
PTR 将IP地址映射成主机地址,ipv4和ipv6的规则是不一样的
MX 指定一主机作为某主机的邮件交换器,如果有多个,先使用数字小的那个MX
CNAME CNAME指别名记录也被称为规范名字。这种记录允许您将多个名字映射到同一台计算机。 通常用于同时提供WWW和MAIL服务的计算机。例如,有一台计算机名为“host.mydomain.com”(A记录)。 它同时提供WWW和MAIL服务,为了便于用户访问服务。可以为该计算机设置两个别名(CNAME):WWW和MAIL。 这两个别名的全称就是“www.mydomain.com”和“mail.mydomain.com”。实际上他们都指向“host.mydomain.com”
函数调用过程:一般根据主机名称找到主机的ip,或者根据主机的ip找到主机的名字,都是通过调用函数gethostbyname和gethostbyaddr来调用解析器代码,解析器代码根据根据系统配置来找到名字服务器的地址,解析器会利用UDP给本地名字服务器发送查询,如果本地名字服务器不知道答案,他会用internet中的名字服务器来查询
查找主机名最重要的函数是gethostbyname 如果成功返回一个hostent的指针,该结构包含ipv4或ipv6地址,函数如下
struct hostent gethostbyname(const char*hostname);
struct hostent
{
char*h_name; // 主机规范名字
char**h_aliases; //别名
inth_addrtype; //AF_INET/AF_INET6
inth_lenght; //4/16
char**h_addr_list //地址链表
}
gethostbyname 函数出现错误的时候,并不设置errno这个变量,而是将h_errno设置定义在<neetdb.h>中的下面的错误值
HOST_NOT_FOUND
TRY_AGAIN
NO_RECOVERY
NO_DATA
hstrerror函数类似于strerror 使用的是h_error这个变量
gethostbyname2函数如下
struct hostent*gethostbyname2(const char* hostname, int family)
这个函数family是AF_INET 或者AF_INET6
如果family设置成AF_INET的话,就会在DNS中查找RR为A的记录,如果没有找到则返回空,如果找到了,看又没有设置RES_USE_INET6若选项未设置则返回IPV4 地址,若设置了则返回ipv4地址到ipv6地址的映射 ,同时更新长度
如果family设置的是AF_INET6的话,在DNS中主机记录为hostname中AAAA的记录,如果找到了则返回,如果没有找到则返回空
而函数structhostent* gethostbyname(const char* hostname)
这个函数,如果没有设置RES_USE_INET6则搜索A记录,如果找到返回,如果没有找到则返回错误,如果设置了RES_USR_INET先找AAAA记录,如果没找到则找A记录
struct hostent*gethostbyaddr(const char* addr,size_t len, int family)
使用参数addr(in_addr类型)的ip地址来找主机,是与gethostbyname函数相反的,len是代表in_addr的长度,family是可以是AF_INET或者AF_INET6
int uname(struct utsname* name)
获得主机的名称
struct utsname
{
charsysname[size];
charnodename[size];//主机名字
charrelease[size1];
charversion[size];
charmachine[size]
}
并没有说统一的size和size1的大小,每个系统都不一样。
int gethostname(char name,size_tnamelen)也能够获得主机的名称;
struct servent* getservbyname(constchar sername ,const char*proto);
根据服务名称来找servent这个结构体中的详细信息
struct servent
{
char*s_name;
char**s_aliases;
intport
char*s_proto
}
struct servent* getservbyport(int port, constchar*proto)
根据端口来找servent的详细信息