2015-07-10 138 views
2

我試圖將一個域名解析爲一個ipv4地址。爲什麼linux的IPv4地址需要16個字節而不是4個

下面是我在做

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,並在google上搜索了一下,但在addr_len上找不到任何東西。還請注意,我沒有設置AI_V4MAPPED標誌。

+1

我認爲這是相關的:http://stackoverflow.com/questions/15608707/why-is-zero-padding-needed-in-sockaddr-in –

回答

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個字節用於該端口,4個字節用於IPv4地址和8個字節的填充,以達到struct sockaddr的長度。

這就是說:你的問題是錯了,這不是IPv4地址(這將只是struct in_addr這實際上只是4個字節)而是IPv4的套接字地址。但是,這裏仍然有8個字節被「浪費」。

+1

POSIX根據需要定義了'sa_family'和'sa_data'字段在'struct sockaddr'中,但只指定'sa_data'是一個可變長度的字段(即C99術語中的一個靈活數組)。所以並不要求'sa_data'有14個字節,但Linux選擇這樣做。 FreeBSD也做同樣的事情,但它在'struct sockaddr'的開頭增加了一個'sa_len'字段。 –

+0

好評,這就是我*懷疑的*。因此,「爲什麼」仍然是一個有效的問題,應該首先針對Linux設計'struct sockaddr'。 –

相關問題