sockaddr和sockaddr_storage之间的区别

zer*_*uno 4 c sockets

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];
}
Run Code Online (Sandbox Code Playgroud)

tor*_*rek 8

storage变体意味着"与最大可能大小一样大",并且也正确对齐(因此它可以保存IPv6地址,或IPv4地址,或ISO协议地址,甚至AF_UNIX路径名或其他).可以把它想象成bin/barrel/breadbox /(其他最喜欢的存储项),它足以容纳"任何套接字地址",无论它是什么类型的套接字地址.IPv4地址(struct sockaddr_in)很小,显然无法在其中保存IPv6地址,但是struct sockaddr_storage具有宽敞的货物区域.

原来struct sockaddr可能应该是这么大,但事实并非如此.所以这基本上是一个历史错误的解决方法.

(您在上面引用的版本中没有对齐项,这看起来很可疑.)

  • 它不能(包含`sockaddr_in6`).旧的`sockaddr`是16个字节,`struct sockaddr_in6`是32个字节.在我看过/使用过的系统上,`storage`版本长128个字节. (3认同)
  • @DarthMoon:是的。这在某种程度上是一个历史错误:他们可能应该采用“void *”。如果您使用的是 inet (不是 inet6)连接,您需要实际 `sockaddr_in` 的实际地址。如果您使用 inet6 连接,则需要实际 `sockadder_in6` 的实际地址。如果您使用的是 unix 域连接,则需要实际 `sockaddr_un` 的实际地址。如果您正在编写一个需要为其他人提供“空间”以“塞入”其中任何一个的库,则需要提供一个实际的 sockaddr_storage。 (2认同)