Puedo ver por qué es útil para convertir sockaddr
en sockaddr_in
, pero no entiendo cómo es posible. Por lo que he leído, son del mismo tamaño y sockaddr_in
se agrega con sin_zero
para que sea del mismo tamaño. Me gustaría saber cómo sabe el compilador dónde obtener la información de sockaddr_in
si se presenta de forma diferente a sockaddr
.Por qué podemos lanzar sockaddr a sockaddr_in
Respuesta
Es posible porque normalmente lanza los punteros, no las estructuras en sí. Hace lo que en lenguaje natural significa "por favor, trate este puntero a un socket structure
como un puntero a un internet socket structure
en su lugar". El compilador no tiene problemas para volver a interpretar el puntero.
Esta es la descripción más detallada tomada a partir de los comentarios:
A sockaddr
es de 16 bytes de tamaño - los primeros dos bytes son la sa_family
, y los 14 bytes restantes son el sa_data
que son datos arbitrarios. Un sockaddr_in
también tiene 16 bytes de tamaño: los primeros 2 bytes son sin_family
(siempre AF_INET
), los siguientes 2 bytes son sin_port
, los siguientes 4 bytes son sin_addr
(dirección IP) y los últimos 8 bytes son sin_zero
que no se utiliza en IPv4 y se proporciona solo para garantizar 16 bytes. De esta forma, puede mirar primero al sockaddr.sa_family
, y si es AF_INET
, entonces interprete el sockaddr
completo como .
A sockaddr_in
no se almacena dentro del campo sockaddr.sa_data
. El sockaddr
completo es el sockaddr_in
completo (cuando sockaddr.sa_family
es AF_INET
, es decir). Si se toma un puntero sockaddr*
y echarlo a un puntero sockaddr_in*
, entonces:
sockaddr.sa_family
essockaddr_in.sin_family
- bytes 0-1 de
sockaddr.sa_data
sonsockaddr_in.sin_port
- bytes 2-5 son
sockaddr_in.sin_addr
- bytes 6 -13 son
sockaddr_in.sin_zero
.
- 1. cómo se hace la estructura sockaddr a sockaddr_in - sockets de red C++ ubuntu UDP
- 2. ¿Por qué lanzar a una interfaz?
- 3. ¿Por qué volver a lanzar excepciones?
- 4. ¿Por qué CLR vuelve a lanzar ThreadAbortException?
- 5. ¿Por qué lanzar nulo a Object?
- 6. Cómo obtener la dirección IP de sockaddr
- 7. Comprender struct sockaddr
- 8. sockaddr_in identificador no declarado
- 9. C# Bitwise Operaciones en cortocircuitos - ¿Por qué lanzar a int?
- 10. ¿Por qué lanzar a objeto al comparar con nulo?
- 11. ¿Por qué podemos vincular a archivos js en otro dominio?
- 12. ¿Por qué no podemos usar assertion para métodos públicos?
- 13. struct sockaddr_un v/s sockaddr - C (Linux)
- 14. ¿Por qué `struct sockaddr` contiene un campo de familia de direcciones?
- 15. Lanzar/no-lanzar una excepción basada en un parámetro: ¿por qué no es una buena idea?
- 16. ¿Por qué es imposible lanzar una excepción desde __toString()?
- 17. Por qué lanzar/convertir de int devuelve un asterisco
- 18. Java: ¿por qué no puedo lanzar una excepción en Comparator?
- 19. C#: ¿Por qué no podemos tener métodos internos/funciones locales?
- 20. ¿Por qué no podemos usar C-strings como SEL?
- 21. ¿Por qué no podemos sobrecargar "=" usando la función amigo?
- 22. ¿Por qué no podemos usar uniones externas en CTE recursivo?
- 23. ¿Podemos tener múltiples NSAutoReleasePools? ¿Por qué sería esto necesario?
- 24. ¿Por qué no podemos bloquear un tipo de valor?
- 25. rendimiento constructor estático y por qué no podemos especificar beforefieldinit
- 26. ¿Por qué no podemos cambiar FetchRequest en NSFetchedResultsController?
- 27. ¿Por qué no podemos inicializar miembros dentro de una estructura?
- 28. por qué no podemos crear nuestro propio objeto ostream
- 29. ¿Podemos tener funciones virtuales estáticas? Si no, ¿POR QUÉ?
- 30. Por qué no podemos tener "enum" enum tipo
Parece extraño porque la variable que se supone que almacena la dirección en sockaddr es sa_data que es char [14], pero sockaddr_in usa un corto sin signo. Supongo que el compilador leerá el primer número corto sin firmar de bytes del char [14] y hará que la dirección, y el resto de char [14] sean los datos que se enviarán? Además, si agrego los tamaños de las dos estructuras, no parecen ser del mismo tamaño. sin_zero parece demasiado grande. ¡Solo estoy tratando de entender qué está pasando aquí! –
Un 'sockaddr' tiene 16 bytes de tamaño; los primeros dos bytes son' sa_family', y los 14 bytes restantes son 'sa_data', que son datos arbitrarios. Un 'sockaddr_in' también tiene 16 bytes de tamaño: los primeros 2 bytes son' sin_family' (siempre 'AF_INET'), los siguientes 2 bytes son' sin_port', los siguientes 4 bytes son 'sin_addr' (dirección IP) , y los últimos 8 bytes son 'sin_zero' que no se utilizan en IPv4 y se proporcionan solo para garantizar 16 bytes. De esta forma, puedes mirar 'sockaddr.sa_family' primero, y si es' AF_INET' luego interpretar todo el 'sockaddr' como' sockaddr_in'. –
Un 'sockaddr_in' no está almacenado dentro del campo' sockaddr.sa_data'. Toda la 'sockaddr' ** es ** la totalidad de' sockaddr_in' (cuando 'sockaddr.sa_family' es' AF_INET', eso es). Si toma un puntero 'sockaddr *' y lo convierte en un puntero 'sockaddr_in *', 'sockaddr.sa_family' es' sockaddr_in.sin_family', los bytes 0-1 de 'sockaddr.sa_data' son' sockaddr_in.sin_port', bytes 2-5 son 'sockaddr_in.sin_addr', y los bytes 6-13 son' sockaddr_in.sin_zero'. –