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

时间:2022-09-29 20:02:59

I can see why it is useful to cast sockaddr to sockaddr_in, but I don't understand how this is possible. From what I've read, they're the same size and sockaddr_in is added with sin_zero to make it the same size. I would like to know how the compiler knows where to get the information from sockaddr_in if it is layed out differently to sockaddr.

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

1 个解决方案

#1


16  

It is possible because you normally cast pointers, not the structures themselves. You do what in natural language means "please treat this pointer to a socket structure as a pointer to an internet socket structure instead". Compiler has no problems to re-interpret the pointer.

这是可能的,因为你通常会投射指针,而不是结构本身。你用自然语言做的意思是“请把这个指针作为指向互联网套接字结构的指针替换为套接字结构”。编译器重新解释指针没有问题。

Here is more detailed description taken up from comments:

以下是评论中更详细的描述:

A sockaddr is 16 bytes in size - the first two bytes are the sa_family, and the remaining 14 bytes are the sa_data which is arbitrary data. A sockaddr_in is also 16 bytes in size - the first 2 bytes are the sin_family (always AF_INET), the next 2 bytes are the sin_port, the next 4 bytes are the sin_addr (IP address), and the last 8 bytes are the sin_zero which is unused in IPv4 and provided only to ensure 16 bytes. This way, you can look at sockaddr.sa_family first, and if it is AF_INET then interpret the entire sockaddr as a sockaddr_in.

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。

A sockaddr_in is not stored inside of sockaddr.sa_data field. The entire sockaddr is the entire sockaddr_in (when sockaddr.sa_family is AF_INET, that is). If you take a sockaddr* pointer and cast it to a sockaddr_in* pointer, then:

sockaddr_in不存储在sockaddr.sa_data字段中。整个sockaddr是整个sockaddr_in(当sockaddr.sa_family是AF_INET时,就是这样)。如果你带一个sockaddr *指针并将其转换为sockaddr_in *指针,那么:

  • sockaddr.sa_family is sockaddr_in.sin_family
  • sockaddr.sa_family是sockaddr_in.sin_family
  • bytes 0-1 of sockaddr.sa_data are sockaddr_in.sin_port
  • sockaddr.sa_data的字节0-1是sockaddr_in.sin_port
  • bytes 2-5 are sockaddr_in.sin_addr
  • 字节2-5是sockaddr_in.sin_addr
  • bytes 6-13 are sockaddr_in.sin_zero.
  • 字节6-13是sockaddr_in.sin_zero。

#1


16  

It is possible because you normally cast pointers, not the structures themselves. You do what in natural language means "please treat this pointer to a socket structure as a pointer to an internet socket structure instead". Compiler has no problems to re-interpret the pointer.

这是可能的,因为你通常会投射指针,而不是结构本身。你用自然语言做的意思是“请把这个指针作为指向互联网套接字结构的指针替换为套接字结构”。编译器重新解释指针没有问题。

Here is more detailed description taken up from comments:

以下是评论中更详细的描述:

A sockaddr is 16 bytes in size - the first two bytes are the sa_family, and the remaining 14 bytes are the sa_data which is arbitrary data. A sockaddr_in is also 16 bytes in size - the first 2 bytes are the sin_family (always AF_INET), the next 2 bytes are the sin_port, the next 4 bytes are the sin_addr (IP address), and the last 8 bytes are the sin_zero which is unused in IPv4 and provided only to ensure 16 bytes. This way, you can look at sockaddr.sa_family first, and if it is AF_INET then interpret the entire sockaddr as a sockaddr_in.

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。

A sockaddr_in is not stored inside of sockaddr.sa_data field. The entire sockaddr is the entire sockaddr_in (when sockaddr.sa_family is AF_INET, that is). If you take a sockaddr* pointer and cast it to a sockaddr_in* pointer, then:

sockaddr_in不存储在sockaddr.sa_data字段中。整个sockaddr是整个sockaddr_in(当sockaddr.sa_family是AF_INET时,就是这样)。如果你带一个sockaddr *指针并将其转换为sockaddr_in *指针,那么:

  • sockaddr.sa_family is sockaddr_in.sin_family
  • sockaddr.sa_family是sockaddr_in.sin_family
  • bytes 0-1 of sockaddr.sa_data are sockaddr_in.sin_port
  • sockaddr.sa_data的字节0-1是sockaddr_in.sin_port
  • bytes 2-5 are sockaddr_in.sin_addr
  • 字节2-5是sockaddr_in.sin_addr
  • bytes 6-13 are sockaddr_in.sin_zero.
  • 字节6-13是sockaddr_in.sin_zero。