Мы можем начать с просмотра фактических структурных схем:
struct hostent {
char *h_name;
char **h_aliases;
int h_addrtype
int h_length;
char **h_addr_list;
}
#define h_addr h_addr_list[0]
struct sockaddr_in {
short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
struct in_addr {
uint32_t s_addr; // IPv4 address
};
Функция gethostbyname()
может выдавать адреса IPv4 или IPv6, в зависимости от значения h_addrtype
. Таким образом, h_addr_list
должен иметь возможность хранить адреса IPv4 или IPv6. Для этого адреса хранятся в виде необработанной памяти, на которую указывают char*
указатели. Чтобы получить фактический адрес, вам нужно привести память к правильному типу адреса, как вы нашли в своем коде:
remoteAddr.sin_addr.s_addr = ((struct in_addr*) (pHostent->h_addr))->s_addr;
Итак, чтобы ответить на ваши вопросы:
- Типы указателей различны, но указанные данные имеют одинаковый тип.
- Нет, данные находятся только в одном месте, на них просто ссылаются указатели другого типа.