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

Как struct sockaddr отличается от struct sockaddr_un ?

Я знаю, что мы используем эти структуры в клиент-серверных модулей,для привязки сокета к адресу сокета.И мы используем оператор cast для его принятия struct sockaddr_un.

Я хочу знать, насколько они разные / похожие, и почему оператор cast?

2 ответов


"struct sockaddr" является общим определением. Он используется любой функцией сокета, которая требует адреса.

"struct sockaddr_un" (адрес "сокетов Unix") - это определенный вид семейства адресов.

более распространенный "struct sockaddr_in" (адрес "интернет-сокета") - это еще один конкретный вид семейства адресов.

приведение-это то, что позволяет API сокетов принимать общий тип параметра, который на самом деле будет одним из нескольких разных фактический тип.

вот хорошая ссылка, которая показывает несколько различных определений семейства адресов:

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


A struct sockaddr обычно используется только в качестве базового типа для указателя. Это структура, предназначенная для покрытия общей начальной последовательности членов в семействе адресов конкретных типов адресов сокетов (struct sockaddr_un, struct sockaddr_in, struct sockaddr_in6 etc.)

единственный член, на которого вы можете положиться struct sockaddr имея единый sa_family_t, указывающее семейство адресов сокетов. Идея заключается в том, что для получения своего рода полиморфизма-вы можете иметь функцию, которая может работать на нескольких разных типы адресов сокетов:

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

/* ... */

обратите внимание, что код, подобный приведенному выше, обычно считается нарушающим правило "строгого сглаживания" в C - если вы хотите сделать это в своем собственном коде, вы должны использовать тип объединения:

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

/* ... */