Why can we cast sockaddr to sockaddr_in

后端 未结 1 1784
走了就别回头了
走了就别回头了 2021-02-13 07:09

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

1条回答
  •  心在旅途
    2021-02-13 07:34

    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.

    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.sa_family is sockaddr_in.sin_family
    • bytes 0-1 of sockaddr.sa_data are sockaddr_in.sin_port
    • bytes 2-5 are sockaddr_in.sin_addr
    • bytes 6-13 are sockaddr_in.sin_zero.

    0 讨论(0)
提交回复
热议问题