2010-09-11 35 views
24

Come è struct sockaddr diverso da struct sockaddr_un?struct sockaddr_un v/s sockaddr - C (Linux)

So che usiamo queste strutture nei moduli client-server, per legare il socket all'indirizzo del socket. E usiamo un operatore cast per accettare struct sockaddr_un.

Voglio sapere quanto sono diversi/simili e perché l'operatore del cast?

risposta

23

"struct sockaddr" è una definizione generica. Viene utilizzato da qualsiasi funzione socket che richiede un indirizzo.

"struct sockaddr_un" (un indirizzo "Unix socket") è un tipo specifico di famiglia di indirizzi.

Il più comune "struct sockaddr_in" (un indirizzo "socket Internet") è un altro tipo specifico di famiglia di indirizzi.

Il cast è ciò che consente alle API socket di accettare un tipo di parametro comune che sarà in realtà uno dei diversi tipi effettivi.

Ecco un buon link che mostra diverse definizioni diverse indirizzo di famiglia:

http://www.cas.mcmaster.ca/~qiao/courses/cs3mh3/tutorials/socket.html

+0

collegamento fornito è dà visione chiara per diff in UNIX e internet prese –

19

Un struct sockaddr genere dovrebbe essere utilizzato solo come tipo di base per un puntatore. Si tratta di una struttura destinata a coprire la sequenza iniziale comune dei membri delle famiglie di indirizzi tipi di indirizzi socket specifico (struct sockaddr_un, struct sockaddr_in, struct sockaddr_in6 etc.)

L'unico membro che si può fare affidamento su struct sockaddr avente un singolo sa_family_t, indicando la famiglia di indirizzi socket. L'idea è che per ottenere una sorta di polimorfismo - si può avere una funzione che può operare su diversi tipi di indirizzi presa:

void foo(struct sockaddr *sa) 
{ 
    switch(sa->sa_family) 
    { 
    case AF_INET: { 
     struct sockaddr_in *sa_in = (struct sockaddr_in *)sa; 

     /* AF_INET processing */ 
    } 

    case AF_UNIX: { 
     struct sockaddr_un *sa_un = (struct sockaddr_un *)sa; 

     /* AF_UNIX processing */ 
    } 

/* ... */ 

Nota però che il codice come sopra è generalmente considerato per rompere il "aliasing rigorosa" regola in C - se si vuole farlo nel proprio codice, si suppone di utilizzare un tipo di unione:

union sockaddr { 
    struct sockaddr sa; 
    struct sockaddr_in sin; 
    struct sockaddr_un sun; 
    /* ... */ 
}; 

void foo(union sockaddr *sa_union) 
{ 
    struct sockaddr *sa = (struct sockaddr *)sa_union; 

    switch(sa->sa_family) 
    { 
    case AF_INET: { 
     struct sockaddr_in *sa_in = (struct sockaddr_in *)sa; 

     /* AF_INET processing */ 
    } 

    case AF_UNIX: { 
     struct sockaddr_un *sa_un = (struct sockaddr_un *)sa; 

     /* AF_UNIX processing */ 
    } 

/* ... */ 
+1

@ caf - Grazie – Pavitar