为什么sin_addr在结构in_addr中?

时间:2012-12-20 19:29:18

标签: c sockets unix

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

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

此处成员sin_addr的类型为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;   // e.g. AF_INET, AF_INET6
    unsigned short   sin_port;     // e.g. htons(3490)
    unsigned long    s_addr ; 
    char             sin_zero[8];  // zero this if you want to
};

3 个答案:

答案 0 :(得分:28)

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

答案 1 :(得分:8)

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

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

答案 2 :(得分:7)

struct in_addr不仅仅是一个整数,因为它可能超过in_addr_t。在许多系统中,它有一个union,这种实现的原因是class A/B/C addresses,现在没有使用。

Unix网络编程第1卷详细解释了历史原因:

  

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