Estructuras

El propósito de esta sección no es enseñar el concepto de estructuras en programación, sino enseñar cómo se usan éstas en la programación de Sockets en C. Si no sabes lo que es una estructura, mi consejo es leer un buen tutorial de C. Por el momento, digamos simplemente que una estructura es un tipo de dato que es un conglomerado, o sea, que puede contener otros tipos de datos, los cuales son agrupados todos juntos en un único tipo definido por el programador.

Las estructuras son usadas en la programación de sockets para almacenar información sobre direcciones. La primera de ellas es struct sockaddr, la cual contiene información del socket.

struct sockaddr 
{ 
   unsigned short sa_family;  /* familia de la dirección */ 
   char sa_data[14];          /* 14 bytes de la dirección del protocolo */  
}; 

    

Pero, existe otra estructura, struct sockaddr_in, la cual nos ayuda a hacer referencia a los elementos del socket.

struct sockaddr_in 
{ 
   short int sin_family;        /* Familia de la Dirección              */ 
   unsigned short int sin_port; /* Puerto                               */
   struct in_addr sin_addr;     /* Dirección de Internet                */
   unsigned char sin_zero[8];   /* Del mismo tamaño que struct sockaddr */ 
}; 
    

Nota. sin_zero puede ser configurada con ceros usando las funciones memset() o bzero() (Ver los ejemplos más abajo).

La siguiente estructura no es muy usada pero está definida como una unión.

Como se puede ver en los dos ejemplos de abajo (ver la sección de nombre Un ejemplo de Servidor de Flujos y la sección de nombre Un ejemplo de Cliente de Flujos), cuando se declara, por ejemplo “client” para que sea del tipo sockaddr_in, luego se hace client.sin_addr = (...).

De todos modos, aquí está la estructura:

    
struct in_addr 
{
   unsigned   long s_addr;
};

Finalmente, creo que es mejor hablar sobre la estructura hostent. En el ejemplo de Cliente de Flujos (ver la sección de nombre Un ejemplo de Cliente de Flujos), se puede ver cómo se usa esta estructura, con la cual obtenemos información del nodo remoto[1].

Aquí se puede ver su definición:

    
struct hostent 
{   
   char *h_name;                   /* El nombre oficial del nodo.               */
   char **h_aliases;               /* Lista de Alias.                           */
   int h_addrtype;                 /* Tipo de dirección del nodo.               */
   int h_length;                   /* Longitud de la dirección.                 */
   char **h_addr_list;             /* Lista de direcciones del nombre del       */
                                   /* servidor.                                 */
   #define h_addr  h_addr_list[0]  /* Dirección, para la compatibilidad con     */
                                   /* anteriores.                               */
};

Esta estructura está definida en el fichero netdb.h.

Al principio, es posible que estas estructuras nos confundan mucho. Sin embargo, después de empezar a escribir algunas líneas de código, y tras ver los ejemplos que se incluyen en este tutorial, será mucho más fácil entenderlas. Para ver cómo se pueden usar estas estructuras, recomiendo ver los ejemplos de la sección de nombre Un ejemplo de Servidor de Flujos y la sección de nombre Un ejemplo de Cliente de Flujos.

Notas

[1]

“nodo”'' será la traducción del término en inglés ``host'', que se usará a lo largo de este texto. Nota del T.