Structs
struct addrinfo
addrinfo
es una estructura utilizada en programación de sockets para almacenar información sobre direcciones de red y servidores. Esta estructura es útil cuando estás escribiendo código que necesita configurar sockets de red, como crear un servidor o un cliente, y deseas almacenar toda la información relevante en un solo lugar.
ai_flags
: Se utiliza para especificar opciones adicionales durante la resolución de direcciones mediantegetaddrinfo
.AI_PASSIVE
: Para usar con servidores, indica que la dirección IP del host local debe asignarse a las estructuras de socket.AI_CANONNAME
: Para obtener el nombre canónico del host.AI_NUMERICHOST
: Para evitar la resolución de nombres de dominio, si ya se tiene una dirección IP numérica.AI_NUMERICSERV
: Similar a AI_NUMERICHOST, pero para el número de puerto
ai_family
: Especifica la familia de direcciones, comoAF_INET
para IPv4 oAF_INET6
para IPv6.AF_UNSPEC
: No especifica IPv4 o IPv6, permitiendo cualquiera.AF_INET
: Para IPv4.AF_INET6
: Para IPv6.
ai_socktype
: Especifica el tipo de socket, comoSOCK_STREAM
para sockets TCP oSOCK_DGRAM
para sockets UDP.SOCK_STREAM
: Para sockets de flujo (TCP).SOCK_DGRAM
: Para sockets de datagramas (UDP).
ai_protocol
: Especifica el protocolo a utilizar, comoIPPROTO_TCP
para TCP oIPPROTO_UDP
para UDP.IPPROTO_TCP
: Para el protocolo TCP.IPPROTO_UDP
: Para el protocolo UDP.
ai_addr
: Un puntero a una estructurasockaddr
que contiene la información de dirección.ai_addrlen
: La longitud de la estructurasockaddr
.ai_canonname
: Un nombre canónico asociado con la dirección.ai_next
: Un puntero al siguiente elemento en la lista enlazada deaddrinfo
. Esto es útil cuandogetaddrinfo()
devuelve múltiples resultados.
Es posible que no necesites escribir en estas estructuras con frecuencia; en muchos casos, una llamada a getaddrinfo()
para completar tu struct addrinfo
será todo lo que necesites. Sin embargo, antes de realizar la llamada a getaddrinfo()
es recomendable vaciar completamente la estructura mediante memset()
.
struct sockaddr
struct sockaddr
es una estructura que actúa como un tipo de dato genérico para representar direcciones de red en la programación de sockets en C. Puede adaptarse tanto a direcciones IPv4 como a direcciones IPv6, lo que la hace versátil y esencial en el desarrollo de aplicaciones de red.
La estructura
struct sockaddr
almacena información de dirección de socket para varios tipos de sockets.
sa_family
puede ser una variedad de cosas, pero en este documento será AF_INET
(IPv4) o AF_INET6
(IPv6) para todo lo que hacemos. sa_data
contiene una dirección de destino y un número de puerto para el socket. Esto puede ser un tanto engorroso ya que no deseas empaquetar manualmente la dirección en sa_data
.
struct sockaddr_in (IPv4)
Para lidiar con struct sockaddr
, los programadores crearon una estructura paralela: struct sockaddr_in
("in" de "Internet") para usar con IPv4.
Y aquí está la parte importante: un puntero a una struct sockaddr_in
se puede convertir en un puntero a una struct sockaddr
y viceversa. Entonces, incluso si connect()
requiere un struct sockaddr*
, todavía puedes usar una struct sockaddr_in
y convertirla en el último momento.
Esta estructura facilita la referencia a los elementos de la dirección del socket. Ten en cuenta que sin_zero
(que se incluye para rellenar la estructura al tamaño de una struct sockaddr
) debe configurarse con todos los ceros utilizando la función memset()
. Además, observa que sin_family
corresponde a sa_family
en una struct sockaddr
y debe configurarse como 'AF_INET'. Finalmente, el sin_port
debe estar en Network Byte Order (utilizando htons()
).
Observa que el campo sin_addr
es una estructura struct in_addr
. ¿Qué es eso? Bueno, sin dramatizar demasiado, es uno de los unions más impresionantes de todos los tiempos
¡Vaya! Bueno, solía ser un union, pero parece que esos días han quedado atrás. Menos mal. Entonces, si has declarado 'ina' como del tipo struct sockaddr_in
, entonces 'ina.sin_addr.s_addr' hace referencia a la dirección IP de 4 bytes (en Network Byte Order). Ten en cuenta que incluso si tu sistema aún utiliza el unión espantoso para struct in_addr
, aún puedes hacer referencia a la dirección IP de 4 bytes de exactamente la misma manera que mencioné anteriormente (esto se debe a las definiciones con '#defines').
sockaddr_in6 (IPv6)
sockaddr_in6
es una estructura utilizada en programación de sockets para representar direcciones de red en el contexto de IPv6. A diferencia de la estructura sockaddr_in
, que se utiliza para direcciones IPv4, sockaddr_in6
está diseñada específicamente para IPv6.
Observa que IPv6 tiene una dirección IPv6 y un número de puerto, al igual que IPv4 tiene una dirección IPv4 y un número de puerto.
struct sockaddr_storage
struct sockaddr_storage
está diseñada para ser lo suficientemente grande como para contener tanto estructuras IPv4 como IPv6. Verás, en algunas llamadas, a veces no sabes de antemano si se completará tu struct sockaddr
con una dirección IPv4 o IPv6. Por lo tanto, pasas esta estructura paralela, muy similar a struct sockaddr
pero más grande, y luego la conviertes al tipo que necesitas.
Lo importante es que puedes ver la familia de direcciones en el campo ss_family
. Verifícalo para ver si es AF_INET
o AF_INET6
(para IPv4 o IPv6). Luego puedes convertirlo en struct sockaddr_in
o struct sockaddr_in6
si así lo deseas.
Last updated