sockaddr和sockaddr_storage有何区别?我不理解,因为在代码中它们看起来很相似:
struct sockaddr {
uint8_t sa_len;
sa_family_t sa_family;
char sa_data[14];
}
struct sockaddr_storage {
uint8_t ss_len;
sa_family_t ss_family;
char ss_padding[SIZE];
}
storage
变体旨在“尽可能大”,并且正确对齐(因此可以容纳IPv6地址、IPv4地址、ISO协议地址,甚至是 AF_UNIX
路径名或其他任何类型的套接字地址)。将其视为一个足够大,可以容纳“任何套接字地址”的储物箱/桶子/面包盒(或其他您喜欢的存储物品)。IPv4地址(struct sockaddr_in
)很小,显然无法在其中容纳IPv6地址,但是 struct sockaddr_storage
有一个宽敞的货舱。
原始的 struct sockaddr
可能本应该如此大,但实际上不是。因此,这基本上是对历史错误的一种解决方法。
(您引用的版本中没有对齐项,这似乎令人怀疑。)
struct sockaddr
可以包含一个struct sockaddr_in6
,那么我为什么需要一个struct sockaddr_storage
? - zer0unosockaddr_in6
。旧的sockaddr
是16个字节,而一个struct sockaddr_in6
是32个字节。在我看到/使用的系统上,storage
版本长度为128个字节。 - toreksockaddr
的指针作为参数,而不是sockaddr_storage*
? - user10251509void *
。如果您正在使用inet(而不是inet6)连接,则需要实际的sockaddr_in
地址。如果您正在使用inet6连接,则需要实际的sockadder_in6
地址。如果您正在使用unix域连接,则需要实际的sockaddr_un
地址。如果您正在编写一个需要为其他人提供空间以将其中任何一个推入的库,则需要提供实际的sockaddr_storage。 - torek