1.1 IPv4 套接口地址结构
#include <netinet/in.h>
struct in_addr
{
in_addr_t s_addr ; //32位的IPv4地址,按网络字节序
};
struct sockaddr_in
{
uint8_t sin_len ; //结构体的长度 16
sa_family sin_family ; //AF_INET
in_port_t sin_port ; //16位的TCP或者UDP端口号,
网络字节序
struct in_addr sin_addr ; //32位的IPv4地址,按网络字节序
char sin_zero[8] //未分配
};
注1: POSIX 规范只需要struct sockaddr_in 结构中的3个成员: sin_family , sin_port , sin_addr
注2: POSIX定义的数据类型 :
#include <sys/types.h>
int8_t 带符号的8位整数
uint8_t 无符号的8位整数
int16_t 带符号的16位整数
uint16_t 无符号的16位整数
int32_t 带符号的32位整数
uint32_t 无符号的32位整数
#include <sys/socket.h>
sa_family_t 套接口地址结构的地址族 : AF_XXX
socklen_t 套接口地址结构的长度,一般为uint32_t
#include <netinet/in.h>
in_addr_t IPv4地址,一般为uint32_t
in_port_t TCP或UDP端口,一般为uint16_t
1.2 通 用套接口地址结构
#include <sys/socket.h>
struct sockaddr
{
uint8_t sa_len;
sa_family_t sa_family
char sa_data[4];
};
注: 通用套接口的由来---当作为参数传递给任何一个套接口函数时,套接口地址结构总是通过指针来传递,但通过指针来取得此参数的套接口函数必须处理来自所支持的任何协议族的套接口地址。
ANSI C中有很简单的办法(通用指针类型void * ),但是,套接口函数在ANSI C之前定义,1982年采用了如上的定义。
于是,套接口函数被定义为采用指向通用套接口地址结构的指针
int bind( int, struct sockaddr *, socklen_t ) ;
通用套接口地址结构的唯一用途是给指向特定于协议的地址结构的指针转换类型。
1.3 IPv6 套接口地址结构
#include <netinet/in.h>
struct in6_addr
{
uint8_t s6_addr[16]; //128位IPv6地址,网络字节序
};
struct sockaddr_in6
{
uint8_t sin6_len; //结构体的长度 28
sa_family_t sin6_family; //AF_INET6
in_port_t sin6_port; //传输层端口,网络字节序
uint32_t sin6_flowinfo; //flow information ,未定义
struct in6_addr sin6_addr; //IPv6地址,网络字节序
uint32_t sin6_scope_id; //接口
}
1.4 新的通用套接口地址结构
作为IPv6套接口API一部分而定义,相比struct sockaddr,新的struct sockaddr_storage足以容纳系统所支持的任何套接口地址结构。
#include <netinet/in.h>
struct sockaddr_storage
{
uint8_t ss_len;
sa_family_t ss_family
};
1.5 各套接口地址结构比较