名稱node
getaddrinfo, freeaddrinfo, gai_strerror - 網絡地址和服務轉換服務器
提要網絡
#include <sys/types.h> #include <sys/socket.h> #include <netdb.h> int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); void freeaddrinfo(struct addrinfo *res); const char *gai_strerror(int errcode);
描述socket
已知node和service,能夠肯定一個網絡主機和其中的一個服務,getaddrinfo()返回一個或多個addrinfo類型的結構體,每個addrinfo結構體包含一個網絡地址,該地址能夠在調用bind(2)和connect(2)時使用。 getaddrinfo函數結合了gethostbyname(3)和getservbyname(3)的功能,同時getaddrinfo是可重入的,容許程序消除IPv4&IPv6的依賴。函數
struct addrinfo{ int ai_flags; int ai_family; int ai_socktype; int ai_prototype; socklen_t ai_addrlen; struct sockaddr *ai_addr; char *ai_canonname; struct addrinfo *next; };
hints參數指向一個addrinfo類型的結構體,做爲篩選返回的套結字地址結構的標準。若是hints爲不爲NULL,它指向的addrinfo結構體的ai_family, ai_socktype, ai_prototype指定返回的套結字地址集的篩選標準。oop
ai_family 該域指定返回的套結字地址的地址族,有效值包括AF_INET和AF_INET6。若是指定爲AF_UNSPEC,那麼函數返回與node和service相關的任何地址族的套結字地址(包括IPv4和IPv6)。spa
ai_socktype 該域指定返回的套結字地址集的協議。指定爲0表示任何協議的套結字地址都會被返回。prototype
ai_flags 該域指定一些附加選項,多個選項能夠經過或(||)操做結合起來。指針
hints中的其餘域必需要麼爲0要麼爲NULL。若是指定hints爲NULL,等價與ai_socktype=ai_prototype=0&ai_family=AF_UNSPEC&ai_flags=AI_V4MAPP||AI_ADDRCONFIG.code
node要麼爲數值型的網絡地址(對於IPv4爲點分十進制表示法,對於IPv6爲十六進制字符串格式),要麼是一個網絡主機域名,固然其對應的網絡地址將會被尋找而且解析。若是hints.ai_flags包含AI_NUMERICHOST,那麼node必須指定爲數值型的網絡地址。AI_NUMERIC抑制任何潛在的冗餘網絡主機地址尋找。
若是hints.ai_flags中指定AI_PASSIVE,而且node爲NULL,那麼返回的套結字地址將會適用與bind()函數,返回的地址將會包含「通用地址「(對於IPv4爲INADDR_ANY,對於IPv6爲IN6ADDR_ANY_INIT),「通用地址」通常用於服務器端程序,用於接受來自任何網絡主機的鏈接。若是node不爲NULL,那麼AI_PASSIVE將會被忽略。
若是hints.ai_flags中沒有指定AI_PASSIVE, 那麼返回的套結字地址將會適用於connect,sendto,和sendmsg函數。若是node爲NULL,那麼返回的網絡地址將會被設置爲迴環接口地址(loopback interface address)(對於IPv4爲INADDR_LOOPBACK,對於IPv6爲IN6ADDR_LOOPBACK_INIT),該地址一般被用於和在相同主機上運行的同級程序進行通訊的應用。
service設置返回的地址結構中的port,若是該參數爲一個服務名稱,將會被轉換爲相應的端口號。該參數也能夠被指定爲十進制數,而且會被簡單的轉換爲二進制。若是service爲NULL,那麼返回的套結字地址中的port將不會被初始化。若是hints.ai_flags中指定了AI_NUMERICSERV而且service不爲NULL,那麼service必須指向一個表明十進制端口號的字符串。在沒必要要的狀況下,AI_NUMERICSERV用於抑制名字解析服務的調用。
node和service不可同時爲NULL。
getaddrinfo函數分配而且初始化一個addrinfo結構體類型的鏈表,每一個節點表明一個返回的套結字地址,返回指向鏈表頭部節點的指針,節點由next域鏈接起來。
有不少緣由致使結果鏈表中會有多個addrinfo結構體:網絡主機是分散的,或者能夠經過多種協議訪問(AF_INET或者AF_INET6),或者相同的服務(service)對於多種套結字類型都是有效的(SOCK_STREAM或者SOCK_DGRAM)。正常狀況下,應用程序應該使用函數返回的套結字地址順序使用地址,getaddrinfo()函數所使用的排序函數定義在RFC 3484;對於某些特定的系統,這個順序能夠經過修改/etc/gai.conf(>=glibc 2.5)被改變。
若是hints.ai_flags包含AI_CANONNAME,那麼返回的鏈表中的第一個addrinfo結構體的ai_canonname域被設置爲指向主機的官方名稱。
返回的鏈表中的addrinfo結構體中的其餘域按以下初始化:
*ai_family, ai_socktype, ai_prototype域返回建立套結字(socket)的參數(這些域與socket()函數相應的參數具備相同的含義)。例如ai_family能夠是AF_INET或者AF_INET6; ai_socktype可使SOCK_STREAM或者SOCK_DGRAM; ai_prototype能夠是套結字的相關協議。
*指向套結字地址的指針被賦給ai_addr域;套結字地址的長度,以字節爲單位,被賦給ai_addrlen.
若是hints.ai_flags指定了AI_V4MAPPED,而且ai_family被指定爲AF_INET,而且沒有找到IPv6地址,那麼IPv4映射的IPv6地址將會被返回。若是hints.ai_flags同時指定了AI_V4MAPPED和AI_ALL, 那麼IPv6和IPv4映射的IPv6地址將會被返回。若是AI_V4MAPPED沒有被指定,那麼AI_ALL將會被忽略。
freeaddrinfo()函數釋放動態分配給res這個臨界鏈表的地址空間。
返回值:
getaddrinfo成功執行返回0,或者返回相應的非0錯誤碼:
EAI_ADDRFAMILY, EAI_AGAIN, EAI_BADFLAGS, EAI_FAIL, EAI_FAMILY, EAI_MEMORY,EAI_NODATA, EAI_NONAME, EAI_SERVICE,EAI_SOCKTYPE, EAI_SYSTEM.