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

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

解答

这是可能的,因为您通常转换指针,而不是结构本身。您所做的自然语言中的意思是“请将此指向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_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

Logo

更多推荐