addrinfo結(jié)構(gòu)是getaddrinfo函數(shù)用來保存主機(jī)地址信息的結(jié)構(gòu)體。在頭文件Ws2tcpip.h中定義。
typedef struct addrinfo {
} ADDRINFOA,
ai_flags:
表示getaddrinfo要使用的選項(xiàng),可賦的值在Winsock2.h中有定義,且可以是幾個(gè)值的組合。
AI_PASSIVE 0x01 | 套接字地址將用于bind函數(shù) |
AI_CANONNAME 0x02 | 規(guī)范名稱(canonical name)在第一個(gè)ai_canonname成員中返回 |
AI_NUMERICHOST 0x04 | getaddrinfo中的nodename參數(shù)必須為numeric string,即地址字符串 |
AI_ADDRCONFIG 0x0400 | The getaddrinfo will resolve only if a global address is configured. The IPv6 and IPv4 loopback address is not considered a valid global address. This option is only supported on Windows Vista or later |
AI_NON_AUTHORITATIVE 0x04000 | The address information is from a secure channel. This option is only supported on Windows Vista or later for the NS_EMAIL namespace. |
AI_SECURE 0x08000 | The address information is from a secure channel. This option is only supported on Windows Vista or later for the NS_EMAIL namespace. |
AI_RETURN_PREFERRED_NAMES 0x010000 | The address information is for a preferred name for a user. This option is only supported on Windows Vista or later for the NS_EMAIL namespace |
ai_family:
地址族。可賦的值在Winsock2.h中有定義。在Vista及之后的SDK中,頭文件的組織方式發(fā)生了變化,地址族的值在Ws2def.h中定義,而Winsock2.h自動(dòng)包含了Ws2def.h。Ws2def.h不應(yīng)該被直接使用。
現(xiàn)在支持的值有AF_INET和AF_INET6,分別表示Ipv4和Ipv6的Internet地址族。其他的值,如AF_NETBIOS,需要安裝了相關(guān)協(xié)議才有效。值得注意的是,這些AF開頭的常量都可以換成PF開頭,值是一樣的。
下表列出了一些常用的地址族
AF_UNSPEC 0 | 地址族不限定 |
AF_INET 2 | Ipv4地址族 |
AF_NETBIOS 17 | The NetBIOS address family. This address family is only supported if a Windows Sockets provider for NetBIOS is installed. |
AF_INET6 23 | Ipv6地址族 |
AF_IRDA 26 | The Infrared Data Association (IrDA) address family. This address family is only supported if the computer has an infrared port and driver installed. |
AF_BTM 32 | The Bluetooth address family. This address family is only supported if a Bluetooth adapter is installed on Windows Server 2003 or later. |
ai_socktype:
套接字類型??少x的值在Winsock2.h中定義了。
下表列出winsock2支持的套接字類型
SOCK_STREAM 1 | 流式套接字,使用TCP協(xié)議。如果ai_family定義為AF_IRDA,則ai_socktype只能設(shè)為流式套接字 |
SOCK_DGRAM 2 | 數(shù)據(jù)報(bào)套接字,使用UDP協(xié)議 |
SOCK_RAW 3 | 原始套接字,允許應(yīng)用程序操作IP層協(xié)議的首部數(shù)據(jù)。要操作Ipv4頭部,socket必須設(shè)置IP_HDRINCL屬性,要操作ipv6頭部,socket必須設(shè)置IPV6_HDRINCL屬性 |
SOCK_RDM 4 | Provides a reliable message datagram. An example of this type is the Pragmatic General Multicast (PGM) multicast protocol implementation in Windows, often referred to as reliable multicast programming. |
SOCK_SEQPACKET 5 | Provides a pseudo-stream packet based on datagrams. |
In Windows Sockets 2, new socket types were introduced. An application can dynamically discover the attributes of each available transport protocol through the WSAEnumProtocols function. So an application can determine the possible socket type and protocol options for an address family and use this information when specifying this parameter. Socket type definitions in the Winsock2.h and Ws2def.h header files will be periodically updated as new socket types, address families, and protocols are defined.
winsock1.1只支持SOCK_DATAGRAM 和SOCK_STREAM.
ai_protocol:
協(xié)議類型??扇〉闹等Q于ai_address和ai_socktype的值。所有的值都在Winsock2.h和Wsrm.h中定義了。
Vista之后的SDK中,ai_protocol可取的值在IPPROTO枚舉中列出了,IPPROTO在Ws2def.h中定義。
如果ai_protocol設(shè)為0,則調(diào)用者不希望限定協(xié)議類型,服務(wù)提供者(如getaddrinfo函數(shù))會(huì)自動(dòng)選擇合適的協(xié)議類型。對Ipv4和Ipv6之外的協(xié)議,將ai_protocol設(shè)為0
下表是常用的協(xié)議類型
IPPROTO_TCP 6 | TCP協(xié)議,當(dāng)ai_family為AF_INET或者AF_INET6且ai_socktype為SOCK_STREAM時(shí)有效 |
IPPROTO_UDP 17 | UDP協(xié)議,當(dāng)ai_family為AF_INET或者AF_INET6且ai_socktype為SOCK_DGRAM時(shí)有效 |
IPPROTO_RM 113 | The PGM protocol for reliable multicast. This is a possible value when the ai_family member is AF_INET and the ai_socktype member is SOCK_RDM. On the Windows SDK released for Windows Vista and later, this value is also called IPPROTO_PGM. |
如果ai_family置為AF_IRDA,則ai_protocol必須為0
ai_addrlen:
ai_addr指向的緩沖區(qū)的字節(jié)數(shù)
ai_canonname:
主機(jī)的規(guī)范化名稱(canonical name)
ai_addr:
指向sockaddr結(jié)構(gòu)的指針。getaddrinfo返回的每個(gè)addrinfo結(jié)構(gòu)內(nèi)的ai_addr都指向一個(gè)filled-in套接字地址結(jié)構(gòu)。
ai_next:
指向鏈表中下一個(gè)addrinfo結(jié)構(gòu)的指針,如果是鏈表的最后一個(gè)addrinfo結(jié)構(gòu),則ai_next為NULL。
getaddrinfo提供了獨(dú)立于網(wǎng)絡(luò)協(xié)議的從主機(jī)名(ANSI格式)到網(wǎng)絡(luò)地址的轉(zhuǎn)換。在Ws2tcpip.h中定義,需要附加依賴庫Ws2_32.lib
int WSAAPI getaddrinfo(
);
參數(shù):
nodename:指向NULL結(jié)尾的ANSI字符串,這個(gè)字符串可以是主機(jī)名,或者主機(jī)地址字符串。對于Internet協(xié)議,主機(jī)地址字符串是點(diǎn)間隔十進(jìn)制ipv4地址或者十六進(jìn)制的ipv6地址。
servname:指向NULL結(jié)尾的ANSI字符串,這個(gè)字符串可以是服務(wù)名稱(service name)或者字符串格式的端口號。(注:如果是端口號,則是主機(jī)字節(jié)序的端口的字符串形式。比如,端口是6969的話,那么servname參數(shù)就設(shè)成”6969”即可,不需要先htons(6969),再來轉(zhuǎn)換成字符串)
hints:addrinfo結(jié)構(gòu)體指針,該結(jié)構(gòu)提供調(diào)用者要支持的socket類型的信息。詳見remarks
res:指向由一個(gè)或多個(gè)addrinfo結(jié)構(gòu)體組成的鏈表,包含了主機(jī)的響應(yīng)信息。
返回值:
成功返回0,失敗返回非零的windows sockets error code
Remarks:
用于IPV4和IPV6時(shí),名字解析可以使用DNS,或者本地的hosts文件,或者其他的名稱解析方式。
Ws2tcpip.h里為getaddrinfo定義了別名GetAddrInfoA,這個(gè)函數(shù)的Unicode版本是GetAddrInfoW
Ws2tcpip.h里還定義了GetAddrInfo函數(shù)和ADDRINFOT結(jié)構(gòu),可以根據(jù)是否定義了Unicode來選擇是使用GetAddrInfoA+addrinfo或者GetAddrInfoW+addrinfoW
成功時(shí),通過res參數(shù)返回一個(gè)addrinfo結(jié)構(gòu)組成的鏈表。這個(gè)鏈表可以通過每個(gè)addrinfo結(jié)構(gòu)中的ai_next成員來遍歷,直到遇到NULL指針。在返回的每個(gè)addrinfo結(jié)構(gòu)中,ai_family,ai_socktype和ai_protocol成員都對應(yīng)socket或者WSASocket函數(shù)的參數(shù)。每個(gè)addrinfo結(jié)構(gòu)的ai_addr成員都指向一個(gè)填充好的(filled-in)套接字地址,ai_addr的長度保存在ai_addrlen成員中。
如果nodename是計(jì)算機(jī)名,那么返回該計(jì)算機(jī)的永久(permanent)地址。如果nodename中包含”..localmachine”或者”localhost”字符串,所有注冊了的地址都會(huì)返回。If nodename refers to a cluster virtual server name, only virtual server addresses are returned. See Windows Clustering for more information about clustering.
調(diào)用者可以通過使用hints參數(shù)來告知getaddrinfo希望支持何種socket。關(guān)于hints的設(shè)置,有如下規(guī)則:
ai_family設(shè)置為AF_UNSPEC或PF_UNSPEC表示調(diào)用者接受任何協(xié)議族。
ai_socktype設(shè)置為0,說明調(diào)用者接受任何類型的socket
ai_protocol設(shè)置為0表示調(diào)用者接受任何協(xié)議
ai_addrlen必須設(shè)為0
ai_canonname必須設(shè)為NULL
ai_addr必須設(shè)為NULL
ai_next必須設(shè)為NULL
hints的ai_flags成員有以下可賦的值:
AI_PASSIVE:表示調(diào)用者想在bind函數(shù)中使用getaddrinfo返回的socket地址。
hints的其他成員表示特定的需求。比如,ai_family設(shè)為AF_INET,表示調(diào)用者只處理IPV4,不處理IPV6。ai_socktype設(shè)為SOCK_STREAM表明調(diào)用者只處理TCP,不處理UDP。
如果hints為NULL,getaddrinfo函數(shù)認(rèn)為hints的ai_family設(shè)為了AF_UNSPEC,其他成員均為0。
On Windows Vista and later when getaddrinfo is called from a service, if the operation is the result of a user process calling the service, then the service should impersonate the user. This is to allow security and routing compartments to be properly enforced.
getaddrinfo返回的所有addrinfo結(jié)構(gòu)都是在內(nèi)存中動(dòng)態(tài)分配的,必須在調(diào)用完后使用freeaddrinfo來釋放內(nèi)存
typedef struct addrinfo {
} ADDRINFOA,
ai_flags:
表示getaddrinfo要使用的選項(xiàng),可賦的值在Winsock2.h中有定義,且可以是幾個(gè)值的組合。
AI_PASSIVE 0x01 | 套接字地址將用于bind函數(shù) |
AI_CANONNAME 0x02 | 規(guī)范名稱(canonical name)在第一個(gè)ai_canonname成員中返回 |
AI_NUMERICHOST 0x04 | getaddrinfo中的nodename參數(shù)必須為numeric string,即地址字符串 |
AI_ADDRCONFIG 0x0400 | The getaddrinfo will resolve only if a global address is configured. The IPv6 and IPv4 loopback address is not considered a valid global address. This option is only supported on Windows Vista or later |
AI_NON_AUTHORITATIVE 0x04000 | The address information is from a secure channel. This option is only supported on Windows Vista or later for the NS_EMAIL namespace. |
AI_SECURE 0x08000 | The address information is from a secure channel. This option is only supported on Windows Vista or later for the NS_EMAIL namespace. |
AI_RETURN_PREFERRED_NAMES 0x010000 | The address information is for a preferred name for a user. This option is only supported on Windows Vista or later for the NS_EMAIL namespace |
ai_family:
地址族??少x的值在Winsock2.h中有定義。在Vista及之后的SDK中,頭文件的組織方式發(fā)生了變化,地址族的值在Ws2def.h中定義,而Winsock2.h自動(dòng)包含了Ws2def.h。Ws2def.h不應(yīng)該被直接使用。
現(xiàn)在支持的值有AF_INET和AF_INET6,分別表示Ipv4和Ipv6的Internet地址族。其他的值,如AF_NETBIOS,需要安裝了相關(guān)協(xié)議才有效。值得注意的是,這些AF開頭的常量都可以換成PF開頭,值是一樣的。
下表列出了一些常用的地址族
AF_UNSPEC 0 | 地址族不限定 |
AF_INET 2 | Ipv4地址族 |
AF_NETBIOS 17 | The NetBIOS address family. This address family is only supported if a Windows Sockets provider for NetBIOS is installed. |
AF_INET6 23 | Ipv6地址族 |
AF_IRDA 26 | The Infrared Data Association (IrDA) address family. This address family is only supported if the computer has an infrared port and driver installed. |
AF_BTM 32 | The Bluetooth address family. This address family is only supported if a Bluetooth adapter is installed on Windows Server 2003 or later. |
ai_socktype:
套接字類型。可賦的值在Winsock2.h中定義了。
下表列出winsock2支持的套接字類型
SOCK_STREAM 1 | 流式套接字,使用TCP協(xié)議。如果ai_family定義為AF_IRDA,則ai_socktype只能設(shè)為流式套接字 |
SOCK_DGRAM 2 | 數(shù)據(jù)報(bào)套接字,使用UDP協(xié)議 |
SOCK_RAW 3 | 原始套接字,允許應(yīng)用程序操作IP層協(xié)議的首部數(shù)據(jù)。要操作Ipv4頭部,socket必須設(shè)置IP_HDRINCL屬性,要操作ipv6頭部,socket必須設(shè)置IPV6_HDRINCL屬性 |
SOCK_RDM 4 | Provides a reliable message datagram. An example of this type is the Pragmatic General Multicast (PGM) multicast protocol implementation in Windows, often referred to as reliable multicast programming. |
SOCK_SEQPACKET 5 | Provides a pseudo-stream packet based on datagrams. |
In Windows Sockets 2, new socket types were introduced. An application can dynamically discover the attributes of each available transport protocol through the WSAEnumProtocols function. So an application can determine the possible socket type and protocol options for an address family and use this information when specifying this parameter. Socket type definitions in the Winsock2.h and Ws2def.h header files will be periodically updated as new socket types, address families, and protocols are defined.
winsock1.1只支持SOCK_DATAGRAM 和SOCK_STREAM.
ai_protocol:
協(xié)議類型。可取的值取決于ai_address和ai_socktype的值。所有的值都在Winsock2.h和Wsrm.h中定義了。
Vista之后的SDK中,ai_protocol可取的值在IPPROTO枚舉中列出了,IPPROTO在Ws2def.h中定義。
如果ai_protocol設(shè)為0,則調(diào)用者不希望限定協(xié)議類型,服務(wù)提供者(如getaddrinfo函數(shù))會(huì)自動(dòng)選擇合適的協(xié)議類型。對Ipv4和Ipv6之外的協(xié)議,將ai_protocol設(shè)為0
下表是常用的協(xié)議類型
IPPROTO_TCP 6 | TCP協(xié)議,當(dāng)ai_family為AF_INET或者AF_INET6且ai_socktype為SOCK_STREAM時(shí)有效 |
IPPROTO_UDP 17 | UDP協(xié)議,當(dāng)ai_family為AF_INET或者AF_INET6且ai_socktype為SOCK_DGRAM時(shí)有效 |
IPPROTO_RM 113 | The PGM protocol for reliable multicast. This is a possible value when the ai_family member is AF_INET and the ai_socktype member is SOCK_RDM. On the Windows SDK released for Windows Vista and later, this value is also called IPPROTO_PGM. |
如果ai_family置為AF_IRDA,則ai_protocol必須為0
ai_addrlen:
ai_addr指向的緩沖區(qū)的字節(jié)數(shù)
ai_canonname:
主機(jī)的規(guī)范化名稱(canonical name)
ai_addr:
指向sockaddr結(jié)構(gòu)的指針。getaddrinfo返回的每個(gè)addrinfo結(jié)構(gòu)內(nèi)的ai_addr都指向一個(gè)filled-in套接字地址結(jié)構(gòu)。
ai_next:
指向鏈表中下一個(gè)addrinfo結(jié)構(gòu)的指針,如果是鏈表的最后一個(gè)addrinfo結(jié)構(gòu),則ai_next為NULL。
getaddrinfo提供了獨(dú)立于網(wǎng)絡(luò)協(xié)議的從主機(jī)名(ANSI格式)到網(wǎng)絡(luò)地址的轉(zhuǎn)換。在Ws2tcpip.h中定義,需要附加依賴庫Ws2_32.lib
int WSAAPI getaddrinfo(
);
參數(shù):
nodename:指向NULL結(jié)尾的ANSI字符串,這個(gè)字符串可以是主機(jī)名,或者主機(jī)地址字符串。對于Internet協(xié)議,主機(jī)地址字符串是點(diǎn)間隔十進(jìn)制ipv4地址或者十六進(jìn)制的ipv6地址。
servname:指向NULL結(jié)尾的ANSI字符串,這個(gè)字符串可以是服務(wù)名稱(service name)或者字符串格式的端口號。(注:如果是端口號,則是主機(jī)字節(jié)序的端口的字符串形式。比如,端口是6969的話,那么servname參數(shù)就設(shè)成”6969”即可,不需要先htons(6969),再來轉(zhuǎn)換成字符串)
hints:addrinfo結(jié)構(gòu)體指針,該結(jié)構(gòu)提供調(diào)用者要支持的socket類型的信息。詳見remarks
res:指向由一個(gè)或多個(gè)addrinfo結(jié)構(gòu)體組成的鏈表,包含了主機(jī)的響應(yīng)信息。
返回值:
成功返回0,失敗返回非零的windows sockets error code
Remarks:
用于IPV4和IPV6時(shí),名字解析可以使用DNS,或者本地的hosts文件,或者其他的名稱解析方式。
Ws2tcpip.h里為getaddrinfo定義了別名GetAddrInfoA,這個(gè)函數(shù)的Unicode版本是GetAddrInfoW
Ws2tcpip.h里還定義了GetAddrInfo函數(shù)和ADDRINFOT結(jié)構(gòu),可以根據(jù)是否定義了Unicode來選擇是使用GetAddrInfoA+addrinfo或者GetAddrInfoW+addrinfoW
成功時(shí),通過res參數(shù)返回一個(gè)addrinfo結(jié)構(gòu)組成的鏈表。這個(gè)鏈表可以通過每個(gè)addrinfo結(jié)構(gòu)中的ai_next成員來遍歷,直到遇到NULL指針。在返回的每個(gè)addrinfo結(jié)構(gòu)中,ai_family,ai_socktype和ai_protocol成員都對應(yīng)socket或者WSASocket函數(shù)的參數(shù)。每個(gè)addrinfo結(jié)構(gòu)的ai_addr成員都指向一個(gè)填充好的(filled-in)套接字地址,ai_addr的長度保存在ai_addrlen成員中。
如果nodename是計(jì)算機(jī)名,那么返回該計(jì)算機(jī)的永久(permanent)地址。如果nodename中包含”..localmachine”或者”localhost”字符串,所有注冊了的地址都會(huì)返回。If nodename refers to a cluster virtual server name, only virtual server addresses are returned. See Windows Clustering for more information about clustering.
調(diào)用者可以通過使用hints參數(shù)來告知getaddrinfo希望支持何種socket。關(guān)于hints的設(shè)置,有如下規(guī)則:
ai_family設(shè)置為AF_UNSPEC或PF_UNSPEC表示調(diào)用者接受任何協(xié)議族。
ai_socktype設(shè)置為0,說明調(diào)用者接受任何類型的socket
ai_protocol設(shè)置為0表示調(diào)用者接受任何協(xié)議
ai_addrlen必須設(shè)為0
ai_canonname必須設(shè)為NULL
ai_addr必須設(shè)為NULL
ai_next必須設(shè)為NULL
hints的ai_flags成員有以下可賦的值:
AI_PASSIVE:表示調(diào)用者想在bind函數(shù)中使用getaddrinfo返回的socket地址。
hints的其他成員表示特定的需求。比如,ai_family設(shè)為AF_INET,表示調(diào)用者只處理IPV4,不處理IPV6。ai_socktype設(shè)為SOCK_STREAM表明調(diào)用者只處理TCP,不處理UDP。
如果hints為NULL,getaddrinfo函數(shù)認(rèn)為hints的ai_family設(shè)為了AF_UNSPEC,其他成員均為0。
On Windows Vista and later when getaddrinfo is called from a service, if the operation is the result of a user process calling the service, then the service should impersonate the user. This is to allow security and routing compartments to be properly enforced.
getaddrinfo返回的所有addrinfo結(jié)構(gòu)都是在內(nèi)存中動(dòng)態(tài)分配的,必須在調(diào)用完后使用freeaddrinfo來釋放內(nèi)存