socket address structures
- 从process到kernel
- 从kernel到process
一、IPv4 Socket Address Structure
IPv4 socket address structure 叫做sockaddr_in。
1 struct in_addr { 2 in_addr_t s_addr; /* 32-bit IPv4 address network byte ordered */ 3 }; 4 5 struct sockaddr_in { 6 uint8_t sin_len; /* length of structure (16) */ 7 sa_family_t sin_family; /* AF_INET */ 8 in_port_t sin_port; /* 16-bit TCP or UDP port number */ 9 /* network byte ordered */ 10 struct in_addr sin_addr; /* 32-bit IPv4 address */ 11 /* network byte ordered */ 12 char sin_zero[8]; /* unused */ 13 };
- sin_len, (length member,长度成员),正是因为有了长度成员,才有了变长套接口地址结构的处理。无需检查和使用sin_len
- IPv4和IPv6 address 和TCP or UDP port number(端口号)总是以网络字节序(network byte order)
- sin_zero 通常被置为0,为了方便,我们将整个结构置为0.
- socket address structures 只用在given host。结构体苯磺酸呢不参与不同host的通信。
二、generic Socket Address Structure:
why?
- 当作为参数传递给任一个套接口函数时,套接口地址结构总是通过指针来传递,但通过指针来取得此参数的套接口函数必须处理来自所支持的任何协议族的套接口地址结构。因此通过定义sockaddr来获取不同的套接口地址结构。
1 struct sockaddr { 2 uint8_t sa_len; 3 sa_family_t sa_family; //address family: AF_xxx value 4 char sa_data[14]; /* protocol-specific address */ 5 6 };
所以在调用函数时,必须将指向特定协议的 socket address structure 转换成 指向 generic socket address structure.
如下所示:
struct sockaddr_in serv; /* IPv4 socket address structure */ /* fill in serv{} */ bind(sockfd, (struct sockaddr *) &serv, sizeof(serv)); //显式转换
三、IPv6 Socket Address Structure
1 struct in6_addr { 2 uint8_t s6_addr[16]; /* 128-bit IPv6 address */ 3 /* network byte ordered */ 4 }; 5 #define SIN6_LEN /* required for compile-time tests */ 6 7 struct sockaddr_in6 { 8 uint8_t sin6_len; /* length of this struct (28) */ 9 sa_family_t sin6_family; /* AF_INET6 */ 10 in_port_t sin6_port; /* transport layer port# */ 11 /* network byte ordered */ 12 uint32_t sin6_flowinfo; /* flow information, undefined */ 13 struct in6_addr sin6_addr; /* IPv6 address */ 14 /* network byte ordered */ 15 uint32_t sin6_scope_id; /* set of interfaces for a scope */ 16 };
- 如果系统支持socket address structures.的长度成员,那就一定要定义SIN6_LEN
- IPv6 地址族是AF_INET6,IPv4地址族是AF_INET
- sin6_flowinfo分成低20位(用于流标签),高12位保留
- sin6_scope_id标识范围地址有意义的范围区间
四、New generic Socket Address Structure:
新的struct sockaddr_storage 足以容纳系统所支持的任何套接口地址结构。
1 struct sockaddr_storage { 2 uint8_t ss_len; /* length of this struct (implementation dependent) */ 4 sa_family_t ss_family; /* address family: AF_xxx value */ 5 /* implementation-dependent elements to provide: 6 * a) alignment sufficient to fulfill the alignment requirements of 7 * all socket address types that the system supports. 8 * b) enough storage to hold any type of socket address that the 9 * system supports. 10 */ 11 };
- socket_storage满足最苛刻的对socket address structure的对齐要求
- socket_storage足够大,能够容纳系统支持的任何套接口地址结构。