addrinfo结构体原型:
typedef struct addrinfo {
int ai_flags; //AI_PASSIVE,AI_CANONNAME,AI_NUMERICHOST
int ai_family; //AF_INET,AF_INET6
int ai_socktype; //SOCK_STREAM,SOCK_DGRAM
int ai_protocol; //IPPROTO_IP, IPPROTO_IPV4, IPPROTO_IPV6 etc.
size_t ai_addrlen; //must be zero or a null pointer
char* ai_canonname; //must be zero or a null pointer
struct sockaddr* ai_addr; //must be zero or a null pointer
struct addrinfo* ai_next; //must be zero or a null pointer
}
getaddrinfo()函数原型:
#include<netdb.h> (POSIX规范)
int getaddrinfo( const char *hostname, const char *service, const struct addrinfo *hints, struct addrinfo **result );
hostname:主机名或ipv4的点分十进制串或ipv6的十六进制串;
service:服务名,也可以理解为端口号,比如DNS服务,端口为53,FTP服务端口为21,也可以自己定义端口号,比如1534;
hints:可以是NULL,也可以是指向addrinfo结构体的指针,那么调用者需要往此结构中填充期望返回信息类型的暗示,比如hints.ai_protocol = NULL,则返回的ai_protocol值或为IPPROTO_UDP或为IPPROTO_TCP;再如,如果服务器清楚自己只处理一种类型的套接字,则把hints中的ai_sockettype设置为流式套接字(SOCK_STRESAM)或数据报式套接字(SOCK_DGRAM),避免返回多个结构,故此成员起到过滤的作用;
result:返回符合hints条件的、指向addrinfo结构体链表的指针。
典型的服务器进程只指定service而不指定hostname,同时,指定AI_PASSIVE标志,则返回套接字地址结构中应含有一个INADDR_ANY(对于IPv4)或IN6ADDR_ANY(对于IPv6)的IP地址
struct addrinfo hints;
hints.ai_family = PF_INET;
hints.ai_socktype = SOCK_DGRAM; //返回的服务既支持udp又支持tcp
hints.ai_protocol = IPPROTO_UDP;
hints.ai_flags = AI_PASSIVE;
getaddrinfo(NULL, 1534, &hints, &reslist);
for (res = reslist; res != NULL; res = res->ai_next) {
sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (bind(sock, res->ai_addr, res->ai_addrlen)) { //返回值:成功返回0,失败返回-1.
/*do something*/
}
/* listen(); recvfrom();*/
}
设置ai_flag = AI_CANONNAME;
设置ai_family = AF_INET; 下图为返回的信息。