web-dev-qa-db-ja.com

struct sockaddr_unとsockaddr

struct sockaddrstruct sockaddr_unの違いは何ですか?

ソケットをソケットアドレスにバインドするために、クライアントサーバーモジュールでこれらの構造を使用していることを知っています。また、キャスト演算子を使用してstruct sockaddr_unを受け入れます。

それらがどのように異なる/類似しているのか、そしてなぜキャスト演算子が必要なのか知りたいのですが?

30
Pavitar

「struct sockaddr」は一般的な定義です。アドレスを必要とするすべてのソケット関数で使用されます。

「struct sockaddr_un」(「Unixソケット」アドレス)は、特定の種類のアドレスファミリです。

より一般的に見られる「struct sockaddr_in」(「インターネットソケット」アドレス)は、別の特定の種類のアドレスファミリです。

キャストにより、ソケットAPIは、実際にはいくつかの異なる実際のタイプのいずれかになる共通のパラメータータイプを受け入れることができます。

これは、いくつかの異なるアドレスファミリ定義を示す優れたリンクです。

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

30
paulsm4

struct sockaddrは通常、ポインタの基本型としてのみ使用する必要があります。これは、アドレスファミリ固有のソケットアドレスタイプのメンバーの一般的な初期シーケンスをカバーすることを目的とした構造です(struct sockaddr_unstruct sockaddr_instruct 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 */
    }

/* ... */
23
caf