web-dev-qa-db-ja.com

struct addrinfoとstruct sockaddrの違いは何ですか

私が理解していることから、struct addrinfoはソケットアドレス構造を準備するために使用され、struct sockaddrにはソケットアドレス情報が含まれています。しかし、実際にはどういう意味ですか? struct addrinfoには、struct sockaddrへのポインターが含まれています。なぜそれらを分離しておくのですか? sockaddr内のすべてのものをaddr_infoに結合できないのはなぜですか?

私はここで推測していますが、それらを分離する理由は、構造体を渡すときにスペースを節約するためですか?たとえば、bind()呼び出しでは、必要なのはポート番号とインターネットアドレスだけです。したがって、これらは両方ともstruct sockaddrにグループ化されます。したがって、大きな構造体addrinfoの代わりにこの小さな構造体を渡すことができますか?

struct addrinfo {
    int              ai_flags;     // AI_PASSIVE, AI_CANONNAME, etc.
    int              ai_family;    // AF_INET, AF_INET6, AF_UNSPEC
    int              ai_socktype;  // SOCK_STREAM, SOCK_DGRAM
    int              ai_protocol;  // use 0 for "any"
    size_t           ai_addrlen;   // size of ai_addr in bytes
    struct sockaddr *ai_addr;      // struct sockaddr_in or _in6
    char            *ai_canonname; // full canonical hostname

    struct addrinfo *ai_next;      // linked list, next node
};

struct sockaddr {
    unsigned short    sa_family;    // address family, AF_xxx
    char              sa_data[14];  // 14 bytes of protocol address
}; 
25
user2782310

_struct addrinfo_はgetaddrinfo()によって返され、成功すると、指定されたホスト名やサービスのstructsのリンクリストが含まれます。

_ai_addr_メンバーは、実際には_struct sockaddr_ではありません。そのstructは、他のすべてのメンバーを含む一般的なメンバーであり、どのタイプの実際に持っている構造体。 getaddrinfo()に渡すものと、その関数が見つけたものに応じて、_ai_addr_は実際には_struct sockaddr_in_、_struct sockaddr_in6_、またはその他の何かへのポインターになります。その特定のアドレスエントリに適切なもの。これは、それらが「別々」に保たれる理由の1つです。なぜなら、そのメンバーは、さまざまなタイプのstructsの束の1つを指している可能性があるからです。 _struct addrinfo_。これらの異なるstructsには異なるメンバーがあるためです。

これは、おそらくホスト名がある場合にこの情報を取得する最も簡単な方法ですが、唯一の方法ではありません。 IPv4接続の場合、必要に応じて_struct sockaddr_in_構造体を自分で作成し、getaddrinfo()を呼び出すというリガマロールを避けることができます。情報を収集するためにインターネットに出かける必要がある場合は、待つ必要があります。 _struct addrinfo_を使用する必要はまったくありません。

17
Paul Griffiths