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


Cómo es struct sockaddr diferente de struct sockaddr_un ?

Sé que usamos estas estructuras en módulos cliente-servidor,para enlazar el socket a la dirección del socket.Y usamos un operador cast para que acepte struct sockaddr_un.

Quiero saber qué tan diferentes/similares son,y por qué el operador de cast?

Author: Pavitar, 2010-09-11

2 answers

"struct sockaddr" es una definición genérica. Es utilizado por cualquier función de socket que requiere una dirección.

"struct sockaddr_un" (una dirección "Unix sockets") es un tipo específico de familia de direcciones.

La más comúnmente vista "struct sockaddr_in" (una dirección de "socket de Internet") es otro tipo específico de familia de direcciones.

El cast es lo que permite a las API de sockets aceptar un tipo de parámetro común que en realidad será cualquiera de varios tipos reales diferentes tipo.

Aquí hay un buen enlace que muestra varias definiciones de familias de direcciones diferentes:

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

 25
Author: paulsm4,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-11 05:45:21

A struct sockaddr generalmente solo debe usarse como el tipo base para un puntero. Es una estructura destinada a cubrir la secuencia inicial común de los miembros en los tipos de direcciones de socket específicos de la familia de direcciones(struct sockaddr_un, struct sockaddr_in, struct sockaddr_in6 etc.)

El único miembro en el que puede confiar struct sockaddr es un único sa_family_t, indicando la familia de direcciones de socket. La idea es que para obtener una especie de polimorfismo - puede tener una función que puede operar en varias direcciones de socket diferentes tipos:

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

/* ... */

Tenga en cuenta que el código como el anterior generalmente se considera que rompe la regla de "alias estricto" en C - si desea hacer eso en su propio código, se supone que debe usar un tipo de unión:

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
Author: caf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-21 23:35:09