网络编程中4个重要的地址数据结构sockaddr_in sockaddr_in6 sockaddr sockaddr_storage

本文详细介绍了IPv4和IPv6的地址结构,包括struct sockaddr_in、sockaddr_in6等关键数据结构,并对比了两种协议地址的不同之处。


1. IPv4: struct  sockaddr_in (internet), 16个字节

复制代码
 1 struct sockaddr_in {
 2      sa_family_t sin_family;             /* AF_INET */
 3      in_port_t sin_port;                 /* Port number.  */
 4      struct in_addr sin_addr;            /* Internet address.  */
 5 
 6      /* Pad to size of `struct sockaddr'.  */
 7      unsigned char sin_zero[sizeof (struct sockaddr) -
 8                             sizeof (sa_family_t) -
 9                             sizeof (in_port_t) -
10                             sizeof (struct in_addr)];
11 };
12 typedef uint32_t in_addr_t;
13 struct in_addr  {
14     in_addr_t s_addr;                    /* IPv4 address */
15 };
复制代码

2. IPv6: struct sockaddr_in6, 28个字节

复制代码
 1 struct sockaddr_in6 {
 2     sa_family_t sin6_family;    /* AF_INET6 */
 3     in_port_t sin6_port;        /* Transport layer port # */
 4     uint32_t sin6_flowinfo;     /* IPv6 flow information */
 5     struct in6_addr sin6_addr;  /* IPv6 address */
 6     uint32_t sin6_scope_id;     /* IPv6 scope-id */
 7 };
 8 struct in6_addr {
 9     union {
10         uint8_t u6_addr8[16];
11         uint16_t u6_addr16[8];
12         uint32_t u6_addr32[4];
13     } in6_u;
14 
15     #define s6_addr                 in6_u.u6_addr8
16     #define s6_addr16               in6_u.u6_addr16
17     #define s6_addr32               in6_u.u6_addr32
18 };
复制代码

3. 通用结构体1: struct sockaddr(local), 16个字节

1 struct sockaddr { 
2      sa_family_t sa_family;       /* Address family */
3      char sa_data[14];            /* protocol-specific address */
4 };

4. 通用结构体2: struct sockaddr_storage(ss),128个字节

 

复制代码
 1 /* Structure large enough to hold any socket address 
 2 (with the historical exception of AF_UNIX). 128 bytes reserved.  */
 3 
 4 #if ULONG_MAX > 0xffffffff
 5 # define __ss_aligntype __uint64_t
 6 #else
 7 # define __ss_aligntype __uint32_t
 8 #endif
 9 #define _SS_SIZE        128
10 #define _SS_PADSIZE     (_SS_SIZE - (2 * sizeof (__ss_aligntype)))
11 
12 struct sockaddr_storage
13 {
14     sa_family_t ss_family;      /* Address family */
15     __ss_aligntype __ss_align;  /* Force desired alignment.  */
16     char __ss_padding[_SS_PADSIZE];
17 };
### `sockaddr_in` 和 `sockaddr_storage` 的区别 `sockaddr_in` 和 `sockaddr_storage` 是用于处理网络地址信息的结构体,它们在设计目的和使用场景上存在显著差异。 `sockaddr_in` 是专门用于 IPv4 地址的结构体,其定义如下: ```c struct sockaddr_in { sa_family_t sin_family; /* 地址族,AF_INET */ in_port_t sin_port; /* 端口号,网络字节顺序 */ struct in_addr sin_addr; /* IPv4 地址 */ char sin_zero[8]; /* 填充字段,保留 */ }; ``` 该结构体的大小固定,适合用于 IPv4 地址的存储和操作,但不支持 IPv6 地址 [^1]。 相比之下,`sockaddr_storage` 是一个通用的地址存储结构体,其设计目的是为了兼容 IPv4IPv6 地址,同时提供足够的空间以容纳不同类型的地址信息。其定义如下: ```c struct sockaddr_storage { sa_family_t ss_family; /* 地址族 */ char __ss_padding[_SS_PADSIZE]; uint64_t __ss_align; /* 用于内存对齐的字段 */ }; ``` `sockaddr_storage` 的大小通常比 `sockaddr_in` 更大,以确保能够容纳最长的地址结构(如 IPv6 地址)。由于其通用性,`sockaddr_storage` 常用于需要同时处理 IPv4IPv6 地址的场景,例如 `bind()`、`connect()` 等函数的参数传递 [^1]。 ### 使用场景的区别 `sockaddr_in` 适用于仅需要处理 IPv4 地址的场景。由于其结构简单且固定,它在 IPv4 网络编程中广泛使用。然而,当需要同时支持 IPv4IPv6 地址时,`sockaddr_in` 的局限性就显现出来。 `sockaddr_storage` 适用于需要兼容 IPv4IPv6 的场景。例如,在通用网络库中,为了支持多种地址类型,通常会使用 `sockaddr_storage` 作为地址存储的容器。通过检查 `ss_family` 字段,可以判断地址类型,并将其转换为对应的结构体(如 `sockaddr_in` 或 `sockaddr_in6`)进行进一步处理 [^1]。 ### 内存对齐和转换 由于 `sockaddr_storage` 的定义中包含了用于内存对齐的字段(如 `__ss_align`),它能够确保在不同平台上地址结构的正确对齐,从而避免因内存对齐问题导致的访问错误。而 `sockaddr_in` 没有类似的对齐字段,因此在某些平台上可能需要手动对齐 [^1]。 在实际使用中,`sockaddr_storage` 可以通过强制类型转换为 `sockaddr_in` 或 `sockaddr_in6`,从而访问具体的地址信息。例如: ```c struct sockaddr_storage storage; struct sockaddr_in *addr_in = (struct sockaddr_in *)&storage; ``` 通过这种方式,可以动态判断地址类型并访问其字段。然而,这种转换需要确保地址类型与目标结构体匹配,否则可能导致数据访问错误 [^1]。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值