Подтвердить что ты не робот

Почему sin_addr внутри структуры in_addr?

Мое сомнение связано со следующей структурой сокетов в 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
};
4b9b3361

Ответ 1

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.

Ответ 3

struct in_addr - это больше, чем просто целое число, потому что оно может иметь больше, чем in_addr_t. Во многих системах он имеет union, и причина такой реализации заключается в адресах класса A/B/C, которые сейчас не используются.

Unix Network Programming Volume 1 подробно объясняет историческую причину:

Причина, по которой член sin_addr является структурой, а не только in_addr_t, является историческим. Ранее выпуски (4.2BSD) определяли структуру in_addr как union различных структур, чтобы обеспечить доступ к каждому из 4 байтов и к обеим 16-разрядным значениям, содержащимся в 32-битном IPv4-адресе. Это использовалось с адресами класса А, В и С для получения соответствующих байтов адреса. Но с появлением подсети, а затем исчезновение различных классов адресов с бесклассовой адресацией, необходимость в союз исчез. Большинство систем сегодня покончили с union и просто определите in_addr как структуру с одним членом in_addr_t.