web-dev-qa-db-ja.com

なぜin_addr構造内にsin_addrがあるのですか?

私の疑問は、UNIXの次のソケット構造に関連しています。

struct sockaddr_in {
    short            sin_family;   // e.g. AF_INET, AF_INET6
    unsigned short   sin_port;     // e.g. htons(3490)
    struct in_addr   sin_addr;     // see struct in_addr, below
    char             sin_zero[8];  // zero this if you want to
};

ここでメンバーsin_addrはタイプstruct in_addr

しかし、なぜ誰かがそれをしたいのかはわかりませんstruct inaddrは次のとおりです。

struct in_addr {
    unsigned long s_addr;          // load with inet_pton()
};

すべて in_addr hasはただ1つのメンバーですs_addr。なぜこのようなものを持てないのか:

struct sockaddr_in {
    short            sin_family;   // e.g. AF_INET, AF_INET6
    unsigned short   sin_port;     // e.g. htons(3490)
    unsigned long    s_addr ; 
    char             sin_zero[8];  // zero this if you want to
};
50

struct in_addrは、使用しているシステムに応じて、非常に異なる場合があります。オン Windows 例:

typedef struct in_addr {
  union {
    struct {
      u_char s_b1,s_b2,s_b3,s_b4;
    } S_un_b;
    struct {
      u_short s_w1,s_w2;
    } S_un_w;
    u_long S_addr;
  } S_un;
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;

唯一の要件は、メンバーs_addr

29
Carl Norum

なぜなら in_addr構造体には、複数のメンバーを含めることができます。

http://pubs.opengroup.org/onlinepubs/009604599/basedefs/netinet/in.h.html

8
ouah

struct in_addrは、in_addr_tを超える可能性があるため、単なる整数以上です。多くのシステムでは、unionがあり、そのような実装の理由は クラスA/B/Cアドレス であり、現在使用されていません。

Unix Network Programming Volume 1は、歴史的な理由を詳細に説明しています:

sin_addrメンバーがin_addr_tだけでなく構造体である理由は歴史的です。以前のリリース(4.2BSD)は、in_addr構造をさまざまな構造のunionとして定義し、4バイトのそれぞれと32ビットに含まれる16ビット値の両方にアクセスできるようにしました。 IPv4アドレス。これは、クラスA、B、およびCアドレスで使用され、アドレスの適切なバイトをフェッチしました。しかし、サブネット化の出現と、クラスレスアドレス指定によるさまざまなアドレスクラスの消失により、ユニオンの必要性はなくなりました。今日のほとんどのシステムは、unionを廃止し、in_addrを単一のin_addr_tメンバーを持つ構造体として定義しています。

7
Yu Hao