ポインターを期待する関数は、ポインターを に送信するときに、struct sockaddr
送信先のポインターをおそらく型キャストします。そのようにして、彼らはあたかもそれが.sockaddr
struct sockaddr_storage
struct sockaddr
struct sockaddr_storage
struct sockaddr_in
との両方に適合するように設計されています。struct sockaddr_in6
独自の を作成するのではなくstruct sockaddr
、通常、使用している IP バージョンに応じてstruct sockaddr_in
またはを作成します。struct sockaddr_in6
使用する IP バージョンを知ろうとするのを避けるために、struct sockaddr_storage
どちらかを保持できる を使用できます。struct sockaddr
これは、connect()、bind() などの関数によって型キャストされ、その方法でアクセスされます。
これらの構造体はすべて以下に表示されます (パディングは、位置合わせのために実装固有です)。
struct sockaddr {
unsigned short sa_family; // address family, AF_xxx
char sa_data[14]; // 14 bytes of protocol address
};
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
};
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 sockaddr_storage {
sa_family_t ss_family; // address family
// all this is padding, implementation specific, ignore it:
char __ss_pad1[_SS_PAD1SIZE];
int64_t __ss_align;
char __ss_pad2[_SS_PAD2SIZE];
};
ご覧のとおり、関数が IPv4 アドレスを想定している場合、最初の 4 バイトだけを読み取ります (構造体の型が であると想定しているためstruct sockaddr
です。それ以外の場合は、IPv6 の 16 バイト全体を読み取ります)。