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中未使用,仅提供16个字节。这样,您可以先查看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
issockaddr_in.sin_family
- sockaddr.sa_family是sockaddr_in.sin_family
- bytes 0-1 of
sockaddr.sa_data
aresockaddr_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中未使用,仅提供16个字节。这样,您可以先查看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
issockaddr_in.sin_family
- sockaddr.sa_family是sockaddr_in.sin_family
- bytes 0-1 of
sockaddr.sa_data
aresockaddr_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。