2012-02-16 25 views
14

sockaddrsockaddr_inにキャストすることがなぜ有用か分かりますが、これはどういうことが可能か分かりません。私が読んだところでは、彼らは同じサイズで、同じサイズにするためにがsin_zeroで追加されています。コンパイラがsockaddr_inから情報を取得する場所を、sockaddrに別の方法でレイアウトしているかどうかをどのように知っているか知りたいと思います。なぜ私たちはsockaddr_inにsockaddrをキャストできるのですか

答えて

16

通常は構造体そのものではなく、ポインタをキャストすることが可能です。あなたは自然言語で "このポインタをへのポインタとしてsocket structureに代用してください"という意味です。コンパイラはポインタを再解釈するのに何の問題もありません。ここ

コメントから取り、より詳細に説明する。

sockaddrのサイズは16バイトである - 最初の2つのバイトはsa_familyであり、残りの14のバイトは、任意のデータであるsa_dataです。 sockaddr_inも16バイトです。最初の2バイトはsin_family(常にAF_INET)、次の2バイトはsin_port、次の4バイトはsin_addr(IPアドレス)、最後の8バイトはsin_zeroです。 IPv4では未使用であり、16バイトを保証するためだけに提供されます。この方法では、最初にsockaddr.sa_familyを見ることができ、AF_INETの場合は、sockaddrの全体をsockaddr_inと解釈します。

sockaddr_inは、sockaddr.sa_dataフィールドの内部に格納されません。 sockaddr全体がsockaddr_insockaddr.sa_familyAF_INETの場合)です。あなたがsockaddr*ポインタを取り、その後、sockaddr_in*ポインタにキャストした場合:

  • sockaddr.sa_familysockaddr_in.sin_family
  • バイトであるsockaddr.sa_dataの0-1は2-5であるsockaddr_in.sin_port
  • バイトsockaddr_in.sin_addr
  • バイト6 -13は、sockaddr_in.sin_zeroです。
+0

sockaddrにアドレスを格納することになっている変数がchar [14]であるsa_dataなので、sockaddr_inはunsigned shortを使用するため、奇妙に見えます。私は、コンパイラがchar [14]から最初の符号なしの短いバイト数を読み込み、それをアドレスにし、残りのchar [14]が送信されるデータであると仮定していますか? また、2つの構造体のサイズを加算すると、同じサイズではありません。 sin_zeroは大きすぎるようです。私はちょうどここに起こっているものを取得するつもりです! –

+11

'sockaddr'のサイズは16バイトです。最初の2バイトは' sa_family'で、残りの14バイトは任意のデータである 'sa_data'です。 'sockaddr_in'も16バイトのサイズです - 最初の2バイトは' sin_family '(常に' AF_INET')、次の2バイトは 'sin_port'、次の4バイトは' sin_addr'(IPアドレス)最後の8バイトは 'sin_zero'であり、これはIPv4では未使用であり、16バイトを保証するためだけに提供されています。このようにして、 'sockaddr.sa_family'を最初に見ることができ、' AF_INET'なら 'sockaddr'を' sockaddr_in'として解釈します。 –

+6

'sockaddr_in'は' sockaddr.sa_data'フィールドの中には格納されていません。 'sockaddr' **は**' sockaddr_in'( 'sockaddr.sa_family'が' AF_INET'です。)です。 'sockaddr *ポインタを' sockaddr_in * 'ポインタにキャストすると、' sockaddr.sa_family'は 'sockaddr_in.sin_family'、' sockaddr.sa_data'のバイト0-1は 'sockaddr_in.sin_port'バイト2-5は 'sockaddr_in.sin_addr'で、バイト6-13は' sockaddr_in.sin_zero'です。 –

関連する問題