【问题标题】:Difference between sockaddr and sockaddr_storagesockaddr 和 sockaddr_storage 之间的区别
【发布时间】:2013-10-23 05:55:24
【问题描述】:

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];
}

【问题讨论】:

    标签: c sockets


    【解决方案1】:

    storage 变体意味着“尽可能大”,并且也正确对齐(因此它可以保存 IPv6 地址、IPv4 地址或 ISO 协议地址,甚至是 @ 987654324@ 路径名或其他)。将其视为一个 bin/barrel/breadbox/(其他最喜欢的存储项目),它大到足以容纳“任何套接字地址”,无论它是哪种套接字地址。 IPv4 地址 (struct sockaddr_in) 很小,显然不能在其中保存 IPv6 地址,但struct sockaddr_storage 有一个大而宽敞的货物区域。

    原来的struct sockaddr 可能应该有这么大,但不是。所以这基本上是一个历史错误的解决方法。

    (您上面引用的版本中没有对齐项,这似乎很可疑。)

    【讨论】:

    • RFC-2553, RFC-3493 §3.10 - 可移植性添加。
    • 但是如果struct sockaddr 可以包含struct sockaddr_in6 为什么我需要struct sockaddr_storage
    • 它不能(包含sockaddr_in6)。旧的 sockaddr 是 16 个字节,struct sockaddr_in6 是 32 个字节。 storage 版本长 128 字节,在我见过/使用的系统上。
    • @torek 但是我知道的所有套接字函数都需要一个指向 sockaddr 的指针作为参数 - 而不是 sockaddr_storage*
    • @DarthMoon:是的。这在某种程度上是一个历史错误:他们可能应该选择void *。如果您使用的是inet(不是inet6)连接,则需要实际sockaddr_in 的实际地址。如果您使用 inet6 连接,则需要实际sockadder_in6 的实际地址。如果您使用的是 unix 域连接,则需要实际 sockaddr_un 的实际地址。如果您正在编写一个需要为其他人提供空间插入其中任何一个的库,则需要提供一个实际的 sockaddr_storage。
    猜你喜欢
    • 1970-01-01
    • 2013-04-07
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    • 2016-10-07
    • 2014-06-17
    • 1970-01-01
    • 2021-12-25
    相关资源
    最近更新 更多