2012-06-12 10 views
14

Cualquiera podría describir cómo funciona (struct sockaddr *)&server aquí? ¿Es posible lanzar una estructura más grande a una estructura más pequeña?¿Es posible convertir struct a otro?

ver estas estructuras:

// IPv4 AF_INET sockets: 
struct sockaddr_in { 
    short   sin_family; // e.g. AF_INET, AF_INET6 
    unsigned short sin_port;  // e.g. htons(3490) 
    struct in_addr sin_addr;  // see struct in_addr, below 
    char    sin_zero[8]; // zero this if you want to 
}; 

struct in_addr { 
    unsigned long s_addr;   // load with inet_pton() 
}; 

struct sockaddr { 
    unsigned short sa_family; // address family, AF_xxx 
    char    sa_data[14]; // 14 bytes of protocol address 
}; 

Este es el programa principal:

int main(int argc , char *argv[]) 
{ 
     int socket_desc; 
     struct sockaddr_in server; 

    //Create socket 
    socket_desc = socket(AF_INET , SOCK_STREAM , 0); 
    if (socket_desc == -1) 
    { 
     printf("Could not create socket"); 
    } 

    server.sin_addr.s_addr = inet_addr("74.125.235.20"); 
    server.sin_family = AF_INET; 
    server.sin_port = htons(80); 

    //Connect to remote server 
    if (connect(socket_desc , (struct sockaddr *)&server , sizeof(server)) < 0) 
    { 
     puts("connect error"); 
     return 1; 
    } 

    puts("Connected"); 
    return 0; 
} 
+0

relacionados http://stackoverflow.com/questions/3995940/casting-one-c-structure-into-another || http://stackoverflow.com/questions/3766229/casting-one-struct-pointer-to-other-c –

Respuesta

10

Esto es referido como Type Punning. Aquí, ambas estructuras tienen el mismo tamaño, por lo que no hay duda de tamaño de la estructura. Aunque puede convertir casi cualquier cosa en algo, hacerlo con estructuras es propenso a errores.

+0

¿Cómo pueden las funciones connect() acceder a inet_address que está almacenado en 'struct in_addr'? –

+0

Algo como '((struct sockaddr_in *) server-> sin_addr.s_addr)' – Benoit

+0

printf ("addr:% d \ n", ((struct sockaddr_in *) server-> sin_addr.s_addr)); producirá este error: socket.c: 50: 54: error: argumento de tipo no válido de '->' (have 'struct sockaddr_in') ¿por qué? –

3

Puede lanzar sockaddr_in a sockaddr, pero normalmente no puede convertir CUALQUIER estructura a CUALQUIER otra y asumir que las cosas funcionarán correctamente.

6

Esta es la forma de "herencia" de C (observe las comillas). Esto funciona porque C no se preocupa por los datos subyacentes en una dirección, solo como lo representa.

La función determina qué estructura es en realidad utilizando el campo sa_family, y fundiéndolo en el sockaddr_in adecuado dentro de la función.

1

En C, es posible lanzar cualquier cosa a cualquier cosa. Incluso podría omitir el molde en (struct sockaddr *), y probablemente solo obtenga una advertencia del compilador.

Cuestiones relacionadas