1. 程式人生 > >為什麼使用getaddrinfo()函式

為什麼使用getaddrinfo()函式

在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型別列表的。