Это возможно, потому что вы обычно используете указатели, а не сами структуры.Вы делаете то, что на естественном языке означает «пожалуйста, вместо этого обращайтесь с этим указателем на socket structure
как с указателем на internet socket structure
».У компилятора нет проблем с повторной интерпретацией указателя.
Вот более подробное описание, взятое из комментариев:
A sockaddr
имеет размер 16 байтов - первые два байта являются sa_family
, а оставшиеся 14 байтов являются sa_data
, что является произвольными данными.A sockaddr_in
также имеет размер 16 байтов - первые 2 байта sin_family
(всегда AF_INET
), следующие 2 байта sin_port
, следующие 4 байта sin_addr
(IP-адрес)и последние 8 байтов - это sin_zero
, который не используется в IPv4 и предоставляется только для обеспечения 16 байтов.Таким образом, вы можете сначала посмотреть на sockaddr.sa_family
, а если это AF_INET
, то интерпретировать весь sockaddr
как sockaddr_in
.
A sockaddr_in
не хранится внутри sockaddr.sa_data
поле.Весь sockaddr
- это весь sockaddr_in
(когда sockaddr.sa_family
равен AF_INET
, то есть).Если вы возьмете указатель sockaddr*
и приведете его к указателю sockaddr_in*
, то:
sockaddr.sa_family
будет sockaddr_in.sin_family
- байтов 0-1 из
sockaddr.sa_data
sockaddr_in.sin_port
- байты 2-5
sockaddr_in.sin_addr
- байты 6-13
sockaddr_in.sin_zero
.