structure sockaddr un v/s sockaddr-C (Linux)

Comment struct sockaddr différent struct sockaddr_un ?

je sais que nous utilisons ces structures dans des modules client-serveur,pour relier la socket à l'adresse de la socket.Et nous utilisons un opérateur cast pour qu'il accepte struct sockaddr_un.

je veux savoir à quel point ils sont différents / similaires,et pourquoi l'opérateur de la fonte?

26
demandé sur Pavitar 2010-09-11 09:32:48

2 réponses

"struct sockaddr" est une définition générique. Il est utilisé par toute fonction de socket qui nécessite une adresse.

"struct sockaddr_un" (une adresse "Unix sockets") est un type spécifique de famille d'adresses.

le plus souvent vu "struct sockaddr_in" (une adresse "Internet socket") est un autre type de famille d'adresses.

le cast est ce qui permet aux APIs sockets D'accepter un type de paramètre commun qui sera en fait n'importe lequel de plusieurs différents types réels.

voici un bon lien qui montre plusieurs définitions de famille d'adresses différentes:

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

25
répondu paulsm4 2010-09-11 05:45:21

struct sockaddr ne doit généralement être utilisé comme type de base que pour un pointeur. Il s'agit d'une structure destinée à couvrir la séquence initiale commune des membres dans les types d'adresses de socket spécifiques à la famille d'adresses (struct sockaddr_un,struct sockaddr_in,struct sockaddr_in6 etc.)

le seul membre sur lequel vous pouvez compter struct sockaddr est un sa_family_t, indiquant la famille d'adresses des sockets. L'idée est que, pour obtenir une sorte de polymorphisme - vous pouvez avoir une fonction qui peut fonctionner sur plusieurs adresse de socket types:

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 */
    }

/* ... */

notez bien que ce code comme celui ci-dessus est généralement considéré comme enfreindre la règle de "l'alias strict" dans C-si vous voulez faire cela dans votre propre code, vous êtes censé utiliser un type de syndicat:

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 */
    }

/* ... */
20
répondu caf 2017-02-21 23:35:09