Почему 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
};
Ответы
Ответ 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
.
Ответ 2
Поскольку структура in_addr
может содержать более одного члена.
http://pubs.opengroup.org/onlinepubs/009604599/basedefs/netinet/in.h.html
Ответ 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
.