Подтвердить что ты не робот

структура sockaddr_un против sockaddr

Чем struct sockaddr отличается от struct sockaddr_un?

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

Ответ 2

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

Единственным членом, на который вы можете положиться 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 */
    }

/* ... */