分享

addrinfo+getaddrinfo

 fym0121 2011-01-10

addrinfo结构是getaddrinfo函数用来保存主机地址信息的结构体。在头文件Ws2tcpip.h中定义。

typedef struct addrinfo {
  int ai_flags;
  int ai_family;
  int ai_socktype;
  int ai_protocol;
  size_t ai_addrlen;
  char* ai_canonname;
  struct sockaddr* ai_addr;
  struct addrinfo* ai_next;

} ADDRINFOA,
 *PADDRINFOA;

ai_flags:

表示getaddrinfo要使用的选项,可赋的值在Winsock2.h中有定义,且可以是几个值的组合。

 

AI_PASSIVE

0x01

套接字地址将用于bind函数

AI_CANONNAME

0x02

规范名称(canonical name)在第一个ai_canonname成员中返回

AI_NUMERICHOST

0x04

getaddrinfo中的nodename参数必须为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中,头文件的组织方式发生了变化,地址族的值在Ws2def.h中定义,而Winsock2.h自动包含了Ws2def.h。Ws2def.h不应该被直接使用。

现在支持的值有AF_INET和AF_INET6,分别表示Ipv4和Ipv6的Internet地址族。其他的值,如AF_NETBIOS,需要安装了相关协议才有效。值得注意的是,这些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协议。如果ai_family定义为AF_IRDA,则ai_socktype只能设为流式套接字

SOCK_DGRAM

2

数据报套接字,使用UDP协议

SOCK_RAW

3

原始套接字,允许应用程序操作IP层协议的首部数据。要操作Ipv4头部,socket必须设置IP_HDRINCL属性,要操作ipv6头部,socket必须设置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:

协议类型。可取的值取决于ai_address和ai_socktype的值。所有的值都在Winsock2.h和Wsrm.h中定义了。

Vista之后的SDK中,ai_protocol可取的值在IPPROTO枚举中列出了,IPPROTO在Ws2def.h中定义。

如果ai_protocol设为0,则调用者不希望限定协议类型,服务提供者(如getaddrinfo函数)会自动选择合适的协议类型。对Ipv4和Ipv6之外的协议,将ai_protocol设为0

下表是常用的协议类型

 

IPPROTO_TCP

6

TCP协议,当ai_family为AF_INET或者AF_INET6且ai_socktype为SOCK_STREAM时有效

IPPROTO_UDP

17

UDP协议,当ai_family为AF_INET或者AF_INET6且ai_socktype为SOCK_DGRAM时有效

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指向的缓冲区的字节数

ai_canonname:

主机的规范化名称(canonical name)

ai_addr:

指向sockaddr结构的指针。getaddrinfo返回的每个addrinfo结构内的ai_addr都指向一个filled-in套接字地址结构。

ai_next:

指向链表中下一个addrinfo结构的指针,如果是链表的最后一个addrinfo结构,则ai_next为NULL。

 ///////////////////////////////////////////////////////////////////////////////////////

getaddrinfo提供了独立于网络协议的从主机名(ANSI格式)到网络地址的转换。在Ws2tcpip.h中定义,需要附加依赖库Ws2_32.lib

int WSAAPI getaddrinfo(

  __in          const char* nodename,

  __in          const char* servname,

  __in          const struct addrinfo* hints,

  __out         struct addrinfo** res

);

参数:

nodename:指向NULL结尾的ANSI字符串,这个字符串可以是主机名,或者主机地址字符串。对于Internet协议,主机地址字符串是点间隔十进制ipv4地址或者十六进制的ipv6地址。

servname:指向NULL结尾的ANSI字符串,这个字符串可以是服务名称(service name)或者字符串格式的端口号。注:如果是端口号,则是主机字节序的端口的字符串形式。比如,端口是6969的话,那么servname参数就设成”6969”即可,不需要先htons(6969),再来转换成字符串

hints:addrinfo结构体指针,该结构提供调用者要支持的socket类型的信息。详见remarks

res:指向由一个或多个addrinfo结构体组成的链表,包含了主机的响应信息。

返回值:

成功返回0,失败返回非零的windows sockets error code

Remarks:

用于IPV4和IPV6时,名字解析可以使用DNS,或者本地的hosts文件,或者其他的名称解析方式。

Ws2tcpip.h里为getaddrinfo定义了别名GetAddrInfoA,这个函数的Unicode版本是GetAddrInfoW

Ws2tcpip.h里还定义了GetAddrInfo函数和ADDRINFOT结构,可以根据是否定义了Unicode来选择是使用GetAddrInfoA+addrinfo或者GetAddrInfoW+addrinfoW

成功时,通过res参数返回一个addrinfo结构组成的链表。这个链表可以通过每个addrinfo结构中的ai_next成员来遍历,直到遇到NULL指针。在返回的每个addrinfo结构中,ai_family,ai_socktype和ai_protocol成员都对应socket或者WSASocket函数的参数。每个addrinfo结构的ai_addr成员都指向一个填充好的(filled-in)套接字地址,ai_addr的长度保存在ai_addrlen成员中。

如果nodename是计算机名,那么返回该计算机的永久(permanent)地址。如果nodename中包含”..localmachine”或者”localhost”字符串,所有注册了的地址都会返回。If nodename refers to a cluster virtual server name, only virtual server addresses are returned. See Windows Clustering for more information about clustering.

调用者可以通过使用hints参数来告知getaddrinfo希望支持何种socket。关于hints的设置,有如下规则:

ai_family设置为AF_UNSPEC或PF_UNSPEC表示调用者接受任何协议族。

ai_socktype设置为0,说明调用者接受任何类型的socket

ai_protocol设置为0表示调用者接受任何协议

ai_addrlen必须设为0

ai_canonname必须设为NULL

ai_addr必须设为NULL

ai_next必须设为NULL

hints的ai_flags成员有以下可赋的值:

AI_PASSIVE:表示调用者想在bind函数中使用getaddrinfo返回的socket地址。

hints的其他成员表示特定的需求。比如,ai_family设为AF_INET,表示调用者只处理IPV4,不处理IPV6。ai_socktype设为SOCK_STREAM表明调用者只处理TCP,不处理UDP。

如果hints为NULL,getaddrinfo函数认为hints的ai_family设为了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结构都是在内存中动态分配的,必须在调用完后使用freeaddrinfo来释放内存


addrinfo结构是getaddrinfo函数用来保存主机地址信息的结构体。在头文件Ws2tcpip.h中定义。

typedef struct addrinfo {
  int ai_flags;
  int ai_family;
  int ai_socktype;
  int ai_protocol;
  size_t ai_addrlen;
  char* ai_canonname;
  struct sockaddr* ai_addr;
  struct addrinfo* ai_next;

} ADDRINFOA,
 *PADDRINFOA;

ai_flags:

表示getaddrinfo要使用的选项,可赋的值在Winsock2.h中有定义,且可以是几个值的组合。

 

AI_PASSIVE

0x01

套接字地址将用于bind函数

AI_CANONNAME

0x02

规范名称(canonical name)在第一个ai_canonname成员中返回

AI_NUMERICHOST

0x04

getaddrinfo中的nodename参数必须为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中,头文件的组织方式发生了变化,地址族的值在Ws2def.h中定义,而Winsock2.h自动包含了Ws2def.h。Ws2def.h不应该被直接使用。

现在支持的值有AF_INET和AF_INET6,分别表示Ipv4和Ipv6的Internet地址族。其他的值,如AF_NETBIOS,需要安装了相关协议才有效。值得注意的是,这些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协议。如果ai_family定义为AF_IRDA,则ai_socktype只能设为流式套接字

SOCK_DGRAM

2

数据报套接字,使用UDP协议

SOCK_RAW

3

原始套接字,允许应用程序操作IP层协议的首部数据。要操作Ipv4头部,socket必须设置IP_HDRINCL属性,要操作ipv6头部,socket必须设置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:

协议类型。可取的值取决于ai_address和ai_socktype的值。所有的值都在Winsock2.h和Wsrm.h中定义了。

Vista之后的SDK中,ai_protocol可取的值在IPPROTO枚举中列出了,IPPROTO在Ws2def.h中定义。

如果ai_protocol设为0,则调用者不希望限定协议类型,服务提供者(如getaddrinfo函数)会自动选择合适的协议类型。对Ipv4和Ipv6之外的协议,将ai_protocol设为0

下表是常用的协议类型

 

IPPROTO_TCP

6

TCP协议,当ai_family为AF_INET或者AF_INET6且ai_socktype为SOCK_STREAM时有效

IPPROTO_UDP

17

UDP协议,当ai_family为AF_INET或者AF_INET6且ai_socktype为SOCK_DGRAM时有效

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指向的缓冲区的字节数

ai_canonname:

主机的规范化名称(canonical name)

ai_addr:

指向sockaddr结构的指针。getaddrinfo返回的每个addrinfo结构内的ai_addr都指向一个filled-in套接字地址结构。

ai_next:

指向链表中下一个addrinfo结构的指针,如果是链表的最后一个addrinfo结构,则ai_next为NULL。

 ///////////////////////////////////////////////////////////////////////////////////////

getaddrinfo提供了独立于网络协议的从主机名(ANSI格式)到网络地址的转换。在Ws2tcpip.h中定义,需要附加依赖库Ws2_32.lib

int WSAAPI getaddrinfo(

  __in          const char* nodename,

  __in          const char* servname,

  __in          const struct addrinfo* hints,

  __out         struct addrinfo** res

);

参数:

nodename:指向NULL结尾的ANSI字符串,这个字符串可以是主机名,或者主机地址字符串。对于Internet协议,主机地址字符串是点间隔十进制ipv4地址或者十六进制的ipv6地址。

servname:指向NULL结尾的ANSI字符串,这个字符串可以是服务名称(service name)或者字符串格式的端口号。注:如果是端口号,则是主机字节序的端口的字符串形式。比如,端口是6969的话,那么servname参数就设成”6969”即可,不需要先htons(6969),再来转换成字符串

hints:addrinfo结构体指针,该结构提供调用者要支持的socket类型的信息。详见remarks

res:指向由一个或多个addrinfo结构体组成的链表,包含了主机的响应信息。

返回值:

成功返回0,失败返回非零的windows sockets error code

Remarks:

用于IPV4和IPV6时,名字解析可以使用DNS,或者本地的hosts文件,或者其他的名称解析方式。

Ws2tcpip.h里为getaddrinfo定义了别名GetAddrInfoA,这个函数的Unicode版本是GetAddrInfoW

Ws2tcpip.h里还定义了GetAddrInfo函数和ADDRINFOT结构,可以根据是否定义了Unicode来选择是使用GetAddrInfoA+addrinfo或者GetAddrInfoW+addrinfoW

成功时,通过res参数返回一个addrinfo结构组成的链表。这个链表可以通过每个addrinfo结构中的ai_next成员来遍历,直到遇到NULL指针。在返回的每个addrinfo结构中,ai_family,ai_socktype和ai_protocol成员都对应socket或者WSASocket函数的参数。每个addrinfo结构的ai_addr成员都指向一个填充好的(filled-in)套接字地址,ai_addr的长度保存在ai_addrlen成员中。

如果nodename是计算机名,那么返回该计算机的永久(permanent)地址。如果nodename中包含”..localmachine”或者”localhost”字符串,所有注册了的地址都会返回。If nodename refers to a cluster virtual server name, only virtual server addresses are returned. See Windows Clustering for more information about clustering.

调用者可以通过使用hints参数来告知getaddrinfo希望支持何种socket。关于hints的设置,有如下规则:

ai_family设置为AF_UNSPEC或PF_UNSPEC表示调用者接受任何协议族。

ai_socktype设置为0,说明调用者接受任何类型的socket

ai_protocol设置为0表示调用者接受任何协议

ai_addrlen必须设为0

ai_canonname必须设为NULL

ai_addr必须设为NULL

ai_next必须设为NULL

hints的ai_flags成员有以下可赋的值:

AI_PASSIVE:表示调用者想在bind函数中使用getaddrinfo返回的socket地址。

hints的其他成员表示特定的需求。比如,ai_family设为AF_INET,表示调用者只处理IPV4,不处理IPV6。ai_socktype设为SOCK_STREAM表明调用者只处理TCP,不处理UDP。

如果hints为NULL,getaddrinfo函数认为hints的ai_family设为了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结构都是在内存中动态分配的,必须在调用完后使用freeaddrinfo来释放内存

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多