您的位置:首页 > 其它

UNPv1第十一章:高级名字与地址转换

2016-04-26 10:40 344 查看

1.getaddrinfo

getaddrinfo函数能够处理名字到地址以及服务到端口这两种转换,返回的是一个sockaddr结构而不是一个地址列表,这些sockaddr结构随后可由套接字函数直接使用

#include <netdb.h>
int getaddrinfo (const char *hostname, const char *service, const struct addrinfo *hints, struct addrinfo **result) ;
//返回:若成功为0,出错为非0


hostname参数是一个主机名或地址串,service参数是一个服务名或十进制端口字串,本函数通过result指针参数返回一个指向addrinfo结构链表的指针,而addrinfo结构定义在头文件

struct addrinfo {
int          ai_flags;           /* AI_PASSIVE, AI_CANONNAME */
int          ai_family;          /* AF_xxx */
int          ai_socktype;        /* SOCK_xxx */
int          ai_protocol;        /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
socklen_t    ai_addrlen;         /* length of ai_addr */
char        *ai_canonname;       /* ptr to canonical name for host */
struct sockaddr    *ai_addr;     /* ptr to socket address structure */
struct addrinfo    *ai_next;     /* ptr to next structure in linked list */
};


同样,getaddrinfo函数的参数hints也为类型。hints参数可以的一个空指针,也可以指向addrinfo结构的指针,调用者可在这个结构中填入关于期望返回的信息类型的暗示。举例来说,如果指定的服务既支持TCP也支持UDP,那么调用者可以把hints结构中的ai_socktype成员设置成SOCK_DGRAM使得返回的仅仅是适用于数据报套接口的信息。

hints结构中调用者可以设置的成员有:

ai_flags(零个或多个或在一起的AI_xxx值)

ai_family(某个AF_xxx值)

ai_socktype(某个SOCK_xxx值)

ai_protocol

其中ai_flags成员可用的标志值及其含义 例如有 AI_PASSIVE(套接字将用于被动打开),AI_CANONNAME(告知getaddrinfo函数返回主机的规范名字)等等

如果本函数返回成功,那么由result参数指向的变量已被填入一个指针,它指向的是由其中的ai_next成员串联起来的addrinfo结构链表。

我们必须先分配一个hints结构,把它清零后填写需要的字段,再调用getaddrinfo然后遍历一个链表逐个尝试每个返回地址。

2.freeaddrinfo

函数getaddrinfo返回的所有存储空间通过调用freeaddrinfo返还给系统

#include <netdb.h>
void freeaddrinfo (struct addrinfo *ai);


ai应指向getaddrinfo返回的第一个addrinfo结构。在该链表中的所有结构,以及这些机构所指向的动态存储空间都将被释放。

只复制addrinfo结构,而不复制addrinfo结构所指向的其他结构,叫做浅拷贝或浅复制(shallow copy)。复制addrinfo结构,同时复制addrinfo结构所指向的其他结构,称为深拷贝或深复制(deep copy)。

3.getnameinfo

getnameinfo函数与getaddrinfo互补:它以一个套接口地址为参数,返回一个描述主机的字符串和一个描述服务的字符串。这个函数以一种独立于协议的方式提供这些信息

#include <netdb.h>
int getnameinfo (const struct sockaddr *sockaddr, socklen_t addrlen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags) ;
//成功为0,出错为非0(如gai_strerror函数中的表)


sockaddr指向包含协议地址的套接口地址结构,它将会被转换成可读的字符串,addrlen是结构的长度。这个结构和长度通常由accept, recvfrom, getsockname,getpeername返回

待返回的2个直观可读字符串由调用者预先分配存储空间,host和hostlen指定主机字串,serv和servlen指定服务字串。如果调用者不想返回主机字串或者服务字串,那就指定hostlen或者servlen为0.

sock_ntop和getnameinfo的差别在于,前者不涉及DNS,直接返回可输出的IP地址和端口号,后者通常试图给主机和服务的名字。

4. host_serv函数

我们给getaddrinfo设计的第一个接口不需要调用者来分配和填写hints结构。这个host_serv函数以地址族和套接口类型作为参数:

#include "unp.h"
struct addrinfo * host_serv(const char * hostname, const char * service ,int family, int socktype);
//返回:成功返回指向addrinfo结构的指针,出错返回NULL
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: