zoukankan      html  css  js  c++  java
  • 第3章 关于名称和地址族

    3.1 将名称映射到数字

           socket API的大多数实现允许访问把名称映射到其他信息(包括Interenet地址)的名称

    服务(name service)。可以把名称(www.baidu.com)映射到Internet地址,也可以把服务

    (例如:应答echo)的名称映射到端口号。

           解析:把名称映射到数值(地址或端口号)的过程。有很多种方式,一些涉及在后天与

    其它系统交互,另一些严格在本地进行。

           名称服务并不是使TCP/IP工作所必需的。名称只是提供一个间接层次,主机名服务可以访问

    广泛来源的信息,主要是DNS(Domain Name System)和本地配置数据库。

           DNS是一种分布式数据库,用于把像www.baidu.com这样的Domain name 映射到Internet地址

    及其他信息。DNS协议允许连接到Internet的主机使用TCP或UDP从该数据库中检索信息。

           本地配置数据库一般是用于名称-Internet地址映射的特定于操作系统的机

    3.1.1 访问名称服务

          主机名称和服务名称映射到一个地址。

           #include <sys/socket.h>

           #include <netdb.h>        //addrinfo

           int getaddrinfo(const char *restrict host,

                                       const char *restrict service,

                                       const struct addrinfo *restrict hint,

                                       struct addrinfo **restrict res);

                         返回值:若成功返回0,出错返回非0错误码

           需要提供主机名称或地址,服务名称或端口号。若只提供一个名字另一个必须为空指针

    主机名称可以是一个节点名点分十进制法表示的主机地址

           第三个参数是要返回的信息的种类,可以使用一个可选的hint来选择地址hint是一个过滤

    地址的模版。仅使用ai_family, ai_flag, ai_protocol和ai_socktype字段。其它整数字段必须

    设为0并且指针字段为空。它表明系统调用者对那一类端点感兴趣。ai_socktypeai_protocol

    设为0表示我们希望接受所有可能的数据。若hint为NULL:系统被期望处理这种情况,等价于ai_famliy

    设为AF_UNSPEC允许返回任何地址包括AF_INET和AF_INET6),其它字段为0

     

           ai_flags中所用的标志用来指定如何处理地址和名字

    ai_flags                 描述

     

    AI_ADDRCONFIG       查询配置的地址类型(IPv4或IPv6)。设置此标志仅当系统具有特定的地址配置

                                的接口时,getaddrinfo()才会返回该地址族的地址。因此仅当系统具有IPv4的接口

                                时,才会返回IPv4地址,对于IPv6同样。

    AI_ALL                查询IPv4和IPv6地址(仅用于AI_V4MAPPED)

    AI_CANONNAME       需要一个规范名(而不是主机名),类似于一个名称可以解析为许多数字地址一样。

                                可以把多个名称解析成一个IP地址。不过,其中有一个名称被解析为正式(规范)

                                名称。

    AI_NUMERICHOST     以数字格式返回主机地址。如果host不是一个具有有效的数字地址格式的字符串,

                                这个标志导致返回一个错误。

    AI_NUMERICSERV     以端口号返回服务

    AI_PASSIVE        套接字地址用于监听绑定。若后host为NULL,任何返回的addrinfo都将把它们的地址

                                设置为合适的“任意”常量INADDR_ANY(IPv4)或IN6ADDR_ANY_INIT(IPv6).

    AI_V4MAPPED           如果没有找到IPv6地址,则返回映射到IPv6格式的IPv4地址。如果ai_family为

                                AF_INET6,并且没有找到匹配的IPv6地址,那么getaddrinfo()返回IPv4映射的IPv6

                                地址。仅支持IPv4和IPv6主机之间有限的互操作性。

    第四个参数是存储一个指向包含结果的链表的指针

     

           函数getaddrinfo返回一个结构addrinfo的链表,使用freeaddrinfo释放一个或多个结构

    这取决于用ai_next字段链接起来的结构多少。

           addrinfo至少包含:

           struct addrinfo {

                  int                        ai_flags;         /* customize behavior */

                  int                        ai_family;              /* address family */

                  int                        ai_socktype;    /* socket type */

                  int                        ai_protocol;    /* protocol */

                  socklen_t        ai_addrlen;            /* length in bytes of address*/

                  sturct sockaddr *ai_addr;              /* address */

                  char               *ai_canonname      /* canonical name of host */

                  struct addrinfo       *ai_next;        /* next in list */

                  ...

           }

           为什么使用一个链表第一对于主机和服务的每种组合,可能有地址族(v4或v6)和

    套接字类型/协议(流tcp或数据包udp)的多种不同组合表示可能端口。例如:“server.example.net”

    可能具有在v4/tcpv6/udP上的端口1001上进行“垃圾邮件”服务侦听的多个实例。getaddrinfo

    可以返回这两者。第二主机名称可以映射到多个ip地址

     

           两个辅助函数:

           #include <sys/socket.h>

           #include <netdb.h>

           void freeaddrinfo(struct addrinfo *addrlist);

     

           #include <netdb.h>

           const char *gai_strerror(int errorcode);

           如果,getaddrinfo失败不使用perror或strerror生成错误信息而是用gai_strerror将返回的错误码转换为

    错误信息。

     

           函数getnameinfo地址转换成主机名或服务名Internet地址获取主机名称

           #include <sys/socket.h>

           #include <netdb.h>

     

           int getnameinfo(const struct sockaddr *restrict addr,

                                       socklen_t alen, char *restrict host,

                                       socklen_t hostlen, char *restrict service,

                                       socklen_t servlen, unsinged int flags);

    套接字地址(addr)被转换成主机名或服务名。若host非空,它指向一个长度为hostlen字节的缓冲

    区用于存储返回的主机名。若service非空,它指向一个长度为servlen字节的缓冲区用于存储返回的

    服务名。

    flags                     描述

    NI_DGRAM          服务基于数据报非基于流

    NI_NAMEREQD          如果找不到主机名称,将其作为一个错误对待

    NI_NOFQDN        对于本地主机,仅返回完全限定域名的字节名字部分

    NI_NUMERICHOST     以数字形式而非名字返回主机地址

    NI_NUMERICSERV     以数字形式非名字返回服务地址(端口号)

     

           程序需要知道自己的主机名称,使用gethostname。它接受受一个缓冲区和缓冲区长度,并把运行

    调用程序的主机的名称复制到给定的缓冲区。

           #include <unistd.h>

           int gethostname(char *namebuf, size_t buflength);

    若缓冲区长度足够大,通过namebuf返回的字符串以null结尾。若缓冲区不够,则没有指定通过namebuf

    返回的字符串是否以null结尾。

           最大主机长度为HOST_NAME_MAX,不同主机有不同长度。hostname命令可以获取和设置主机名。

     

           3.1.2 其它的地址查询

           这些函数返回的网络配置信息可能存放在许多地方,例如:保存在静态文件中(如:/etc/

    hosts, /etc/serviecs等),或者在命名服务管理(如:DNS, NIS(Network Information Service))。

    这些函数都可以访问它们。

     

           调用gethostent可以找到给定计算机的主机信息

           #include <netdb.h>

           struct hostent *gethostent(void);

                                返回值: 成功返回指针,出错返回NULL

           void sethostnet(int stayopen);

           void endhostent(void);

     

           如果主机数据文件没有打开,gethostent会打开它。函数gethostent返回文件的下一个条目。

    函数sethostent会打开文件,如果文件已经被打开,那么将其回绕。函数endhostent关闭文件。

           gethostent返回时,得到一个指向hostent结构的指针,该结构可能包含一个静态的数据缓冲区。

    每次调用gethostent将会覆盖这个缓冲区。hostent至少包含:

           struct hostent {

                  char  *h_name;            /* name of host */

                  char **h_aliases;    /* pointer to alternate host name arry */

                  int    h_addrtype; /* address type */

                  int      h_length;   /* length in bytes of address */

                  char **h_addr_list; /* pointer to array of network address */

           };

    返回的地址为网络字节顺序。

  • 相关阅读:
    Android学习之APP点击功能闪退问题的处理一
    RN TextInput用法
    OC仿QQ侧滑
    UIKIT_EXTERN和define定义常量
    iOS添加pch文件
    UICollectionView横向分页
    OC,UITableView侧滑删除
    OC图片滑动验证
    OC屏幕手势解锁
    OC分割输入验证码的视觉效果
  • 原文地址:https://www.cnblogs.com/hancm/p/3668356.html
Copyright © 2011-2022 走看看