为什么 linux 的 IPv4 地址占用 16 个字节而不是 4 个字节

Why are linux's IPv4 address taking 16 bytes instead of 4

我正在尝试将域名解析为 ipv4 地址。

这是我正在做的最简单的代码

addrinfo hints, *results;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
int error = getaddrinfo("google.com", 0, &hints, &results);
for(addrinfo* info = results; info; info = info->ai_next)
{
    std::cout << (info->ai_family == AF_INET6 ? "ip6" : "ip4")
              << '[' << info->ai_addrlen << "]: ";
    for(uint i = 0; i < info->ai_addrlen; ++i)
        std::cout << int(((uint8_t*)info->ai_addr)[i]) << ' ';
    std::cout << std::endl;
}
freeaddrinfo(results);

当我运行这个时,它打印:

ip4[16]: 2 0 0 0 216 58 208 238 0 0 0 0 0 0 0 0 
ip4[16]: 2 0 0 0 216 58 208 238 0 0 0 0 0 0 0 0 
ip4[16]: 2 0 0 0 216 58 208 238 0 0 0 0 0 0 0 0

google.com的实际ip是216.58.208.238。所以出于某种原因,对于 ip v4,ai_addr 包含 16 个字节,实际上将地址存储在字节 4 到 8.

我的问题是:其他 12 个字节是什么?

我阅读了 the docs,并用谷歌搜索了一下,但在 addr_len 上什么也没找到。另请注意,我没有设置 AI_V4MAPPED 标志。

我不确定某些标准是否真的要求,但是 struct sockaddr 被定义为包含地址族的 short 和然后是 14 个字节的地址族特定数据。

用作地址的每种类型都必须与其兼容,因此至少具有相同的长度。

对于 struct sockaddr_in(IPv4 的那个),它看起来像这样:

struct sockaddr_in {
    short            sin_family;
    unsigned short   sin_port;
    struct in_addr   sin_addr;
    char             sin_zero[8];
};

地址族2字节,端口2字节,IPv4地址4字节,padding 8字节达到struct sockaddr.

的长度

那是说:你的问题 稍微 错了,这不是 IPv4 地址(那只是 struct in_addr 实际上只有 4 个字节)而是一个套接字IPv4 的地址。尽管如此,这里还是有 8 个字节 "wasted"。