为什么sin_addr在结构体in_addr中?

我的怀疑与UNIX中套接字的以下结构有关:

struct sockaddr_in { short sin_family; // eg AF_INET, AF_INET6 unsigned short sin_port; // eg htons(3490) struct in_addr sin_addr; // see struct in_addr, below char sin_zero[8]; // zero this if you want to }; 

这里成员sin_addr的types是struct in_addr

但是我不明白为什么有人会这样做,因为所有struct inaddr都是这样的:

 struct in_addr { unsigned long s_addr; // load with inet_pton() }; 

所有in_addr只有一个成员s_addr 。 为什么我们不能有这样的事情:

 struct sockaddr_in { short sin_family; // eg AF_INET, AF_INET6 unsigned short sin_port; // eg htons(3490) unsigned long s_addr ; char sin_zero[8]; // zero this if you want to }; 

struct in_addr有时是非常不同的,这取决于你在哪个系统上。 在Windows上 ,例如:

 typedef struct in_addr { union { struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b; struct { u_short s_w1,s_w2; } S_un_w; u_long S_addr; } S_un; } IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR; 

唯一的要求是它包含一个成员s_addr

因为in_addr结构可能包含多个成员。

http://pubs.opengroup.org/onlinepubs/009604599/basedefs/netinet/in.h.html

struct in_addr不仅仅是一个整数,因为它可能比in_addr_t 。 在许多系统中,它有一个union ,这种实现的原因是A / B / C类地址 ,现在不用。

Unixnetworking编程第一卷详细解释了历史原因:

sin_addr成员是一个结构,而不仅仅是一个in_addr_t是历史的。 早期版本(4.2BSD)将in_addr结构定义为各种结构的union ,以允许访问32位IPv4地址中包含的4个字节和16位值中的每一个。 这与A,B和C类地址一起使用来获取地址的相应字节。 但随着子网的出现以及随着无阶级地址的消失,对工会的需求消失了。 今天的大多数系统已经取消了union ,只是将in_addr定义为具有一个in_addr_t成员的结构。