好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

Linux/UNIX网络编程教学课件甘刚第06章名字与地址转换编程.ppt

34页
  • 卖家[上传人]:w****i
  • 文档编号:94546217
  • 上传时间:2019-08-08
  • 文档格式:PPT
  • 文档大小:228KB
  • / 34 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 第6章 名字与地址转换编程,知识点: 域名系统作用 域名系统对应记录 从域名解析对应IP 从IP解析对应域名,现在的网络都是使用名字来访问服务器的,而不是使用地址来访问 那它们是怎么转换的呢?答案就是利用名字与地址的转换函数实现的:gethostbyname和gethostbyaddr在主机名字与IP地址间进行转换,getservbyname和getservbyport在服务名字和端口号间进行转换,并且还要介绍两个与协议无关的getaddrinfo和getnameinfo函数,域名系统就是通常所说的DNS(Domain Name System)系统,而DNS系统主要用于主机名与IP地址间的映射,同时还可以通过主机名或主机地址获取主机的相关信息 那么在DNS系统中是怎样实现主机名与IP地址间的映射的呢?答案就是通过资源记录来实现在DNS中的条目称为资源记录RR(Resource Record),它们主要有以下几类:,(1)AA记录将一个域名地址对应一个2bit的IPv4地址 (2)AAAAAAAA记录(称为“四A”记录)将主机名映射为128位的IPv6地址 (3)NSNS记录用于指定一个域名服务器,它负责定义由哪个域名服务器负责管理维护本区域的记录。

      (4)MX.MX记录用于指定一台主机的域名,所有发送到本域的电子邮件都由这台主机接收 (5)PTRPTR记录(称为“指针记录”)将IP地址映射为主机名 (6)CNAMECNAME代表Canonical Name(规范名字),作用是允许主机建立别名gethostbyname()函数,找主机名最基本的函数gethostbyname(),该函数执行如果成功,它返回一个指向结构hostent的指针,该结构中包含了该主机的所有IPv4地址或IPv6地址;如果失败返回空指针 include struct hostent * gethostbyname (const char * hostname); 参数hostname是主机的域名地址,函数将查询的结果作为参数返回如果失败返回空指针;如果成功此参数返回的非空指针指向如下的hostent结构:,,struct hostent { char * h_name; /*主机的正式名称*/ char * * h_aliases; /*主机的别名列表*/ int h_addrtype; /*主机地址类型*/ int h_length; /*主机地址长度*/ char * * h_addr_list; *主机IP地址的列表*/ }; # define h_addr h_addr_list[0] /*在列表中的第一个地址*/,gethostbyname()函数是怎样工作的,原来gethostbyname函数首先在/etc/hosts文件中查找是否有匹配的主机名。

      如果没有,则根据在域名解析配置文件/etc/resolv.conf中指定的本地域名服务器的地址向本地域名服务器发送地址解析请求如果本地域名服务器能够解析,则返回UDP数据包说明结果,否则本地域名服务器将向上一层的域名服务器发送域名解析请求下面举个例子来看看gethostbyname()函数,#include #include #include main(int argc, const char **argv) { ulong_t addr; struct hostent *hp; char **p; if (argc != 2) { (void) printf(“usage: %s host_name\n“, argv[0]); exit (1); } hp = gethostbyname(argv[1]); if (hp == NULL) { (void) printf(“host information for %s not found\n“, argv[1]); exit (2); } for (p = hp-h_addr_list; *p != 0; p++) { struct in_addr in; char **q; (void) memcpy( },RES_USE_INET6解析器选项,解析器选项是用来通知解析器让gethostbyname返回的是IPv6地址而不是IPv4地址。

      设置该选项的方法有以下3种: (1)应用程序可以设置此选项 (2)如果环境变量RES_OPTIONS中含有串inet6,则此选项打开 (3)在配置文件中如果包含“options inet6”时选项打开,但如果这样设置了,则此选项影响主机上调用解析器函数的所有应用程序,因此这项技术要在结构hostent中返回的IPv6地址可以被主机上的所有应用程序处理时才能使用gethostbyname2函数对IPv6的支持,gethostbyname2()函数,该函数有两个参数,并允许指定地址族 # include struct hostent * gethostbyname2(const char * hostname,int family) 返回:若为非空指针,则表示成功;若为空指针,则表示出错,同时设置h_errno 该函数的返回值与gethostbyname的返回值相同,为一个指向结构hostent的指针该函数的逻辑依赖于参数family和解析器选项RES_USE_INET6,gethostbyaddr()函数,gethostbyaddr()函数的作用是可以查询指定的IP地址对应的主机域名地址。

      函数的形式如下: # include struct hostent * gethostbyaddr(const char * addr, size_t len , int family ); 返回:若为非空指针,则表示成功;若为空指针,则表示出错,同时设置h_errno 该函数同样返回一个指向结构hostent的指针而在参数中,参数addr不是char *类型,而是一个真正指向含有IPv4或IPv6地址的结构in_addr或in6_addr的指针;len是此结构的大小,对于IPv4地址为4,对于IPv6地址为16;参数family为AF_INET或AF_INET6uname()函数,该函数功能如同它的名字一样,即返回当前主机的名字,它返回的信息比较完整下一节将介绍返回主机名字的另一个函数,但它返回的信息就相对少些 经常与函数gethostbyname()一起用来确定本地主机的IP地址它的具体形式如下: # include int uname (struct utsname * name); 返回:若为非负值,则表示成功;若为-1,则表示出错gethostname函数,该函数同样返回当前主机的名字,但返回信息比上节介绍的函数少,该函数形式如下: # include int gethostname(char * name , size_t namelen); 返回:若为0,则表示成功;若为-1,则表示出错。

      name是指向主机名存储位置的指针,namelen是此数组的大小如果有空间,主机名以空字符结束主机名的最大长度通常是由头文件定义的常值MAXHOSTNAMELENgetservbyname和getservbyport函数,函数getservbyname()可以通过服务名来获取服务器端口号,函数的形式如下: # include struct servent * getservbyname (const char * servname, const char * protoname); 返回:若为非空指针,则表示成功;若为空指针,则表示出错函数是getservbyport()函数,该函数的作用是通过端口号来获取服务名,它是反向的查询服务名称,即功能与getservbyname()函数相反下面就来看一下它的具体形式: # include struct servent *getservbyport (int port , const char *protname); 返回:若为非空指针,则表示成功;若为空指针,则表示出错getaddrinfo、gai_strerror和host_serv函数,getaddrinfo()函数在库函数中隐藏了所有协议依赖性,因此应用程序只需要处理由getaddrinfo填写的套接口地址结构即可。

      该函数的形式如下: # include int getaddrinfo (const char * hostname, const char *service, const struct addrinfo * hints, struct addrinfo * * result); 返回:若成功返回0,若出错返回非0gai_strerror()函数,该函数返回的非零错误值的名字和含义如表6-2所示gai_strerror()函数以这些值作为它的一个参数,返回指向对应的出错信息字符串的指针该函数形式如下: # include char * gai_strerror (int error ); 返回:一个指向描述出错信息字符串的指针填写hints结构的函数,即host_serv()函数,它以地址族和套接口类型作为参数,形式如下: # include “unp.h“ struct addrinfo *host_serv (const char * hostname, const char * service, int family, int socktype); 返回:若成功返回指向addrinfo结构的指针,若出错返回NULL。

      freeaddrinfo函数,getaddrinfo()函数返回的存储空间,包括addrinfo结构、ai_addr结构和ai_canonname字符串,都是用malloc动态获取的这些空间可调用freeadddrinfo()函数释放下面就来看一下这个函数 # include void freeaddrinfo (struct addrinfo * ai); 该函数的参数ai指向getaddrinfo返回的第一个addrinfo结构,因此该链表中的所有结构和这些结构所指向的动态存储空间都将被释放这样可以通过它来回收资源,同时如果在getaddrinfo()函数中调用某个操作时失败,也可以调用freeaddrinfo()函数来对错误进行处理使用getaddrinfo的TCP和UDP,有了host_serv()函数后,现在来看一下getaddrinfo在TCP中的应用,先从tcp_connect()函数着手,该函数执行客户程序的一般操作步骤是:创建一个TCP套接口并与服务器建立连接,它的形式如下: # include “unp.h“ int tcp_connect (const char * hostname, const char * servi ce ); 返回:若成功则返回已连接套接口的描述字,若出错则不返回。

      include “unp.h“ int tcp_connect(const char *host, const char *serv) { int sockfd, n; struct addrinfo hints, *res, *ressave; bzero( },,当用此函数时如果getaddrinfo()失败,或所有connect()失败,这个函数(以及在以下描述的给getaddrinfo()提供一些简单接口的其他函数)将终止只有在成功时这个函数才返回 接下来看一下另一个函数tcp_listen(),它是用来执行TCP服务器程序的一般操作步骤,即创建一个TCP套接口,给它捆绑服务器的众所周知端口,并允许接收外来的连接请求,该函数形式如下:,,# include “unp.H“ int tcp_listen (const char 。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.