getaddrinfo函数既能通过主机名获得IP地址(内部使用的是gethostbyname函数),也能通过服务名获得端口号(内部使用的是getservbyname函数)。它是否可重入取决于其内部调用的gethostbyname和getservbyname函数是否是它们的可重入版本。该函数的定义如下:
#include <netdb.h>
int getaddrinfo(const char* hostname, const char* service,
const struct addrinfo* hints, struct addrinfo** result);
hostname参数可以接收主机名,也可以接收字符串表示的IP地址(IPv4采用点分十进制字符串,IPv6则采用十六进制字符串)。同样,service参数可以接收服务名,也可以接收字符串表示的十进制端口号。hints参数是应用程序给getaddrinfo的一个提示,以对getaddrinfo的输出进行更精确的控制。hints参数可以被设置为NULL,表示允许getaddrinfo反馈任何可用的结果。result参数指向一个链表,该链表用于存储getaddrinfo反馈的结果。
结构体addrinfo的定义如下:
struct addrinfo
{
int ai_flags;
int ai_family;// 地址族
int ai_socktype;// 服务类型,SOCK_STREAM或SOCK_DGRAM
int ai_protocol;
socklen_t ai_addrlen;// socket地址ai_addr的长度
char* ai_canonname;//主机的别名
struct sockaddr* ai_addr;// 指向socket地址
struct addrinfo* ai_next;// 指向下一个addrinfo结构的对象
};
该结构体中,ai_protocol成员是指具体的网络协议,其含义和socket系统调用的第三个参数相同,它通常被设置为0。
当我们使用hints参数的时候,可以设置其ai_flags,ai_family,ai_socktype和ai_protocol四个字段,其他字段则必须被设置为NULL。
要注意的是:
getaddrinfo调用结束后,我们必须使用如下配对函数来释放这块内存:
#include <netdb.h>
void freeaddrinfo(struct addrinfo* res);