我可以看到为什么将sockaddr
投射到sockaddr_in
是有用的,但我不明白这是如何实现的。根据我的阅读,它们的大小相同,并sockaddr_in
添加sin_zero
以使其大小相同。我想知道编译器如何知道从sockaddr_in
获取信息的位置,如果它与sockaddr
的布局不同。
答案 0 :(得分:17)
这是可能的,因为你通常会投射指针,而不是结构本身。您使用自然语言执行的操作意味着“请将此指针视为socket structure
作为指向internet socket structure
的指针”。编译器重新解释指针没有问题。
以下是评论中更详细的描述:
sockaddr
的大小为16个字节 - 前两个字节是sa_family
,剩下的14个字节是sa_data
,它是任意数据。 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
。
sockaddr_in
字段中未存储sockaddr.sa_data
。整个sockaddr
是整个sockaddr_in
(当sockaddr.sa_family
为AF_INET
时)。如果您使用sockaddr*
指针并将其转换为sockaddr_in*
指针,则:
sockaddr.sa_family
是sockaddr_in.sin_family
sockaddr.sa_data
的字节0-1是sockaddr_in.sin_port
sockaddr_in.sin_addr
sockaddr_in.sin_zero
。