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

时间:2015-07-10 14:51:02

标签: c++ linux dns ip

我正在尝试将域名解析为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标志。

1 个答案:

答案 0 :(得分:3)

我不确定这是否实际上是某种标准 ,但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个字节,填充为8个字节,长度为struct sockaddr

那说:你的问题是稍微错误,这不是IPv4地址(只是struct in_addr,实际上只有4个字节),而是IPv4的套接字地址。仍然,这里“浪费”了8个字节。