2015-09-17 5 views
5
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 

実際にaddr引数に渡される構造体は、アドレスファミリによって異なります。sockaddrのsa_dataフィールドの目的は何ですか?

struct sockaddr { 
    sa_family_t sa_family; 
    char  sa_data[14]; 
} 

だから、IPv4アドレス(AF_INET)のために、渡されます、実際の構造体はこれです::のようなもののようにsockaddr構造体が定義されている

/* Source http://linux.die.net/man/7/ip */ 

struct sockaddr_in { 
    sa_family_t sin_family; /* address family: AF_INET */ 
    in_port_t  sin_port; /* port in network byte order */ 
    struct in_addr sin_addr; /* internet address */ 
}; 

/* Internet address. */ 
struct in_addr { 
    uint32_t  s_addr;  /* address in network byte order */ 
}; 

バインドコードはsockaddr.sa_family値を読んでいます見つかった値に応じて、sockaddr_inなどの適切な構造体にsockaddr構造体をキャストしますか?

sa_dataが14文字に設定されているのはなぜですか?私が正しいと理解すれば、sa_dataフィールドは、すべてのアドレスファミリタイプに適合する十分なメモリスペースを持つフィールドにすぎませんか?おそらく元の設計者は、14文字がすべての将来のタイプに適合するのに十分な幅であると予想していたと思われます。 glibc manualによれば

+0

https://ja.wikipedia.org/wiki/Type_punning – user3386109

答えて

5

:sa_dataの

長さ14は、本質的に任意です。

そしてFreeBSD developers handbook次のことを言及:

コメントがより 以上があることができほのめかして、ちょうど14バイトの配列としてsa_dataフィールドが宣言されると曖昧、 に注意してください。それらのうち14。

このあいまいさはかなり慎重です。ソケットは非常に強力な インターフェイスです。ほとんどの人はおそらくそれをインターネットのインターフェイス 以上と考えていますが、ほとんどのアプリケーションでこれを使用している可能性があります。 今日のソケットは、インターネットの(より正確には)プロセス間のあらゆる種類の通信に使用できます。 、IP)は です。

はい、sa_familyフィールドは(バインドするための呼び出しでstruct sockaddr*にキャストされます)渡された構造体を治療するための方法を認識するために使用されます。どのように動作するかについては、FreeBSD developers handbookでも詳しく読むことができます。

実際sa_dataは、例えば、16の以上のバイトを含有するsockaddrの「多型」(サブ)タイプがある:

struct sockaddr_un { 
    sa_family_t sun_family;    /* AF_UNIX */ 
    char  sun_path[108];   /* pathname */ 
}; 
3

sockaddr構造体がタグ付けされた共用体として使用されます。 sa_familyフィールドを読み取ることによって、適切なフォームの構造体にキャストできます。

14バイトは任意です。 IPv4アドレスを保持するのに十分な大きさですが、IPv6アドレスを保持するのに十分な大きさではありません。また、両方のために十分な大きさのsockaddr_storage構造体もあります。 MicrosoftのドキュメントをSOCKADDR_STORAGEで読んでみると、それは128バイトで提供され、IPv6よりもはるかに大きい。いくつかのLinuxヘッダーを調べると、少なくともそこにも大きなヘッダーがあるようです。参考のため

、IPv6の構造体は次のとおりです。

struct sockaddr_in6 { 
    u_int16_t  sin6_family; // address family, AF_INET6 
    u_int16_t  sin6_port;  // port number, Network Byte Order 
    u_int32_t  sin6_flowinfo; // IPv6 flow information 
    struct in6_addr sin6_addr;  // IPv6 address 
    u_int32_t  sin6_scope_id; // Scope ID 
}; 

struct in6_addr { 
    unsigned char s6_addr[16]; // IPv6 address 
}; 

あなたが見ることができるように、16バイトs6_addrフィールドは、それ自身で、すでに14バイトsa_dataフィールドよりも大きいです。 sa_familyフィールド以降の合計サイズは26バイトです。

関連する問題