UNIX Network Programming笔记之第十一章(二)

    getaddrinfo函数

    gethostbyname和getservbyname是基于IPv4协议的,getaddrinfo是协议无关的函数,能够处理名字到地址之间以及服务到端口这两种转换, 返回的是一个sockaddr结构而不是一个地址列表。
    
#include<netdb.h>
int getaddrinfo(const char *hostname, const char *service, const struct addrinfo*hints, struct addrinfo **result);
//成功返回0, 出错返回非0
    四个参数的介绍:
    hostname参数: 主机名或地址串(IPv4的点分十进制串或IPv6的十六进制串)
    service参数:服务名或十进制端口号数串
    hints参数:可以是NULL,也可以是一个addrinfo结构的指针,调用者在这个结构中填入关于期望返回的信心类型的暗示
    result参数:返回的结果。
    struct 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
};
    如果函数成功返回, 那么由result参数指向的变量已被填入一个指针,它指向的是由其中的ai_next成员连接起来的addrinfo结构链表。导致返回多个addrinfo结构的情形有以下两个:
    1. 如果与hostname参数关联的地址有多个,那么适用于所请求地址族(由hints的ai_family成员设置)的每个地址都返回一个对应的结构。
    2. 如果service参数指定的服务支持多个套接字类型,那么每个套接字类型都可能返回一个对应的结构,具体取决于hints结构的ai_socktype成员。
    使用的时候,我们先分配一个hints的addrinfo结构,把它清零后填入需要的字段,再调用getaddrinfo, 然后遍历一个链表逐一尝试每个返回地址。

    gai_strerror函数

    将getaddrinfo返回的值作为参数,返回一个对应出错信息串的指针
#include <netdb.h>
const char *gai_strerror(int error);
//返回出错信息串的指针

    freeaddrinfo函数

    由getaddrinfo函数返回的所有存储空间都是动态分配的内存,包括addrinfo结构,ai_addr结构和ai_canonname字符串,需要调用freeaddrinfo释放内存
#include <netdb.h>
void freeaddrinfo(struct addrinfo *ai);
    ai参数应指向getaddrinfo返回的链表的第一个结构指针。这个链表的所有结构以及它们指向的任何动态存储空间都将释放掉。如果我们为保存信息而只是复制这个addrinfo结构,然后调用freeaddrinfo,就会有潜在的危险。因为这个结构本身指向动态分配的内存空间都会被释放。
    浅复制:只复制这个addrinfo结构而不复制由它转而指向的其他结构
    深复制:既复制这个结构,又复制这个结构所指向的所有其他结构

    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);

    可重入函数

    gethostbyname是不可重入的。getaddrinfo是可重入的。
    在一个普通的UNIX进程中发生重入问题的条件是:当它的主控制流中和某个信号处理函数中同时调用函数,会出现不可定义的问题,该函数就是不可重入的。
    errno也是不可重入的,并且标准IO函数库也是不可重入的,我们不应该从信号处理函数中调用标准IO函数。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值