地址族来自Address Family的翻译,可以看成是套接字的类型,即不同的套接字对应不同的地址族。每种类型的套接字都拥有自己独特的通信寻址方式。地址族的取值包括AF_INET、AF_INET6以及AF_UNSPEC等,这些值在Winsock2.h中定义。
sockaddr结构用于存储套接字地址。在Windows Vista之前的版本,sockaddr结构在Winsock2.h中定义,在Windows Vista以及之后的版本中,sockaddr结构在Ws2def.h中定义。其在Winsock2.h中定义的格式为
struct sockaddr { ushort sa_family; char sa_data[14]; };其中,sa_family表示“1 套接字地址族”中提到的地址族;sa_data保存了用于套接字寻址所需要的信息。sa_family的值是AF_INET表示使用IPv4的寻址方式;AF_INET6表示使用IPv6的寻址方式;AF_UNSPEC表示寻址方式不确定,根据主机的服务确定任何合适的寻址方式。在“1 套接字地址族”中提到,不同的地址族对应不同的套接字寻址方式,其寻址所需的信息不同,即sa_data中保存的信息不同。所以,对于sa_family的不同取值,sockaddr结构有不同的格式。
当sa_family的值是AF_INET时,表示使用IPv4的寻址方式,其sockaddr结构对应的格式为
struct sockaddr_in { short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; };其中,sin_family的值必须是AF_INET;sin_port表示端口号;sin_addr表示IP地址;sin_zero[8]是为了保证sockaddr_in的大小与sockaddr相同而进行的填零。也就是说,IPv4的套接字寻址信息包括端口号和IP地址。
当sa_family的值是AF_INET6时,表示使用IPv6的寻址方式,其sockaddr结构对应的格式为
struct sockaddr_in6 { short sin6_family; u_short sin6_port; u_long sin6_flowinfo; struct in6_addr sin6_addr; u_long sin6_scope_id; };当sa_family的值是AF_IRDA时,表示使用红外的寻址方式,其sockaddr结构对应的格式为
typedef struct _SOCKADDR_IRDA { u_short irdaAddressFamily; u_char irdaDeviceID[4]; char irdaServiceName[25]; } SOCKADDR_IRDA, *PSOCKADDR_IRDA, *LPSOCKADDR_IRDA;