在IPv6的应用中getaddrinfo()是很常见的,最常见的形式是:
addrinfo hints;
addrinfo *res = NULL;
memset(&hints,0,sizeof(hints));
hints.ai_family=AF_INET6;
hints.ai_socktype=SOCK_DGRAM;
hints.ai_protocol=IPPROTO_UDP;
hints.ai_flags=AI_NUMERICHOST;
int rc=getaddrinfo((LPCTSTR)"2001:da8:6000:291:21f:d0ff:fed4:928c","6000",&hints,&res);
我们需要的变量是“addrinfo *res”,而hints只是一个中间过程而已。但仔细观察下,我们会发现,相比于hints变量,res也只是增加了IP地址和端口信息而已,并没有其他更多的信息加入。这时候便会有人有疑问:“为什么不像变量hints一样,直接把IP地址和端口直接指定呢?为什么非要绕个弯弯呢?”其实,我在最开始的时候也存在这样的疑问,下面让我们在看一下res在后续程序中被用到的地方。
SOCKET sockSrv=socket(res->ai_family, res->ai_socktype, res->ai_protocol);
但这里貌似没什么特别的(相比于hints而言)。
接着看,
int ret = bind(sockSrv, res->ai_addr, res->ai_addrlen);
char bufSend[50] = "safasf";
rc=sendto(sockClt, bufSend, 4, 0, res->ai_addr,res->ai_addrlen);
注意这里的res->ai_addrlen。这个变量代表地址长度。是在getaddrinfo()函数中自动获得的(当然这个我们也可以自己指定)。
看到这里,应用getaddrinfo()函数的原因已经很明显了-简化res变量的初始化。老实讲,数据类型addrinfo还是有点小复杂的(有兴趣可以研究下),如果每一个内部数据成员都要考虑初始化,还是相对麻烦的。所以,这里引入getaddrinfo()函数,使得addrinfo res的初始化变得清晰而简单。
需要补充的是,getaddrinfo()函数的用途也不只限于此的,至少它的本意是获得所有符合条件的addrinfo类型列表的。