Ответ 1
Это возможно, потому что вы обычно бросаете указатели, а не сами структуры. Вы делаете то, что на естественном языке означает "пожалуйста, обработайте этот указатель на 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
.