为什么我们可以将sockaddr转换为sockaddr_in

时间:2012-02-16 13:27:37

标签: linux sockets tcp udp

我可以看到为什么将sockaddr投射到sockaddr_in是有用的,但我不明白这是如何实现的。根据我的阅读,它们的大小相同,并sockaddr_in添加sin_zero以使其大小相同。我想知道编译器如何知道从sockaddr_in获取信息的位置,如果它与sockaddr的布局不同。

1 个答案:

答案 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中未使用,仅提供1​​6个字节。这样,您可以先查看sockaddr.sa_family,如果是AF_INET,则将整个sockaddr解释为sockaddr_in

sockaddr_in字段中未存储sockaddr.sa_data。整个sockaddr是整个sockaddr_in(当sockaddr.sa_familyAF_INET时)。如果您使用sockaddr*指针并将其转换为sockaddr_in*指针,则:

  • sockaddr.sa_familysockaddr_in.sin_family
  • sockaddr.sa_data的字节0-1是sockaddr_in.sin_port
  • 字节2-5是sockaddr_in.sin_addr
  • 字节6-13是sockaddr_in.sin_zero