套接字地址结构:
首先找到定义套接字地址结构的文件<netinet/in.h>,我使用的ubuntu14.04,路径:/usr/include/netinet/in.h
1.IPV4套接字地址结构
UNIX网络编程中提供的结构
struct in_addr {
in_addr_t s_addr; //存储32位的ipv4地址的变量
};
struct sockaddr_in {
uint8_t sin_len;
sa_family_t sin_family; //AF_NET
in_port_t sin_port; //16位的tcp或者udp端口编号 ,采用网络字节序
struct in_addr sin_addr; //32位的Ipv4地址 ,采用网络字节序
char sin_zero[8]; //一般全部填充为0
};
重点关注sin_family,sin_port,sin_addr这三个成员,有这三个成员的符合posix标准(读者可自行查阅什么是posix标准)int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,sa_family_t等都是POSIX规范要求的数据类型
2.IPV6套接字地址结构
//也是在<netinet/in.h>头文件中定义
1 struct in6_addr {
2 uint8_t s6_addr[16]; /* 128-bit IPv6 address */
3 /* network byte ordered */
4 }
5
6 #define SIN6_LEN /* required for compile-time tests */
7
8 struct sockaddr_in6 {
9 uint8_t sin6_len; /* length of this struct (28) */
10 sa_family_t sin6_family; /* AF_INET6 */
11 in_port_t sin6_port; /* transport layer port# */
12 /* network byte ordered */
13 uint32_t sin6_flowinfo; /* flow information, undefined */
14 struct in6_addr sin6_addr; /* IPv6 address */
15 /* network byte ordered */
16 uint32_t sin6_scope_id; /* set of interfaces for a scope */
17 }
- IPV6的地址族是AF_INET6,IPV4的地址族是AF_INET
- 端口和ipv6地址都是网络字节序,sin6_scope_id标识地址范围
3.老的通用套接字地址结构-了解就好,现在多用新的通用套接字地址结构
在void × 这个通用指针类型还没有出现之前,人们对需要传递套接字地址的函数调用都必须把特定协议的套接字地址结构进行强制类型转换。1 struct sockaddr {
2 sa_family_t sa_family; /* 地址族, AF_xxx */
3 char sa_data[14]; /* 14字节的协议地址 */
4 }4.新的通用套接字地址结构
struct sockaddr_storage {
uint8_t ss_len; /* length of this struct (implementation dependent) */
sa_family_t ss_family; /* address family: AF_xxx value */
/* implementation-dependent elements to provide:
* a) alignment sufficient to fulfill the alignment requirements of
* all socket address types that the system supports.
* b) enough storage to hold any type of socket address that the
* system supports.
*/
- sockaddr_storage能够满足任何苛刻的对齐要求
- sockaddr_storage足够大,能够容纳系统支持的任何套接字地址结构(也就是此套接字地址结构更通用)
- 重要的一点,sockaddr_storage结构中其他字段对用户来说透明(除ss_family和ss_len)。sockaddr_storage必须类型强制转换成或复制到适合ss_family字段所给出地址类型的套接字地址结构中,才能访问其他字段
5.值-结果参数
学习c系,特别是玩指针的时候,这个小玩意儿应该经常被我们有意无意间用到。函数的参数是一个指针,该结构的长度也是一个参数。其实,就是告诉函数了一块可以使用的内存区间,告诉了起始地址和有效范围,函数内部就可以往这块内存写值,函数成功返回后,外部就可以从这块区间取值。这样的参数就称为值-结果参数
- 从进程到内核传递套接字地址结构的函数: bind connect sendto 每个函数以后会一一详解
- 从内核到进程传递套接字地址结构的函数:accept recvfrom getsockname getpeername