bind() - ソケットへの名前の結合
標準
標準/拡張機能 | C/C++ | 依存項目 |
---|---|---|
XPG4.2 |
両方 |
形式
#define _XOPEN_SOURCE_EXTENDED 1
#include <sys/socket.h>
int bind(int socket, const struct sockaddr *address, socklen_t address_len);
#define _OE_SOCKETS
#include <sys/types.h>
#include <sys/socket.h>
int bind(int socket, struct sockaddr *address, int address_len);
機能説明
- パラメーター
- 説明
- socket
- 直前の socket() 呼び出しで戻されたソケット記述子。
- address
- socket に結合される名前が入っている sockaddr 構造体を指すポインター。
- address_len
- address のサイズ (バイト単位)。
socket パラメーターは、socket() 呼び出しにより作成された不特定型のソケット記述子です。
address パラメーターは、socket に結合される名前が入っている、バッファーを指すポインターです。address_len パラメーターは、address が示す バッファーのサイズ (バイト単位) です。AF_UNIX の場合、この関数は、ソケットをクローズする以外にあとで リンク解除する必要のあるファイルを作成します。
AF_INET ドメインで作成されたソケット記述子
struct in_addr
{
ip_addr_t s_addr;
};
struct sockaddr_in {
unsigned char sin_len;
unsigned char sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};
sin_family フィールドは、AF_INET に設定する必要があります。
sin_port フィールドは、アプリケーションの結合先である ポートに設定します。このフィールドは、ネットワーク・バイト順に指定しなければ なりません。sin_port を 0 に設定すると、呼び出し元は、使用可能なポートを割り当てるために、このフィールドをシステムに残します。アプリケーションは、割り当てられたポート番号を見つけるのに、getsockname() を呼び出すことができます。
sin_addr.s_addr フィールドは IP アドレスに設定し、ネットワーク・バイト順に指定する必要があります。複数のネットワーク・インターフェースを持つホスト (マルチホーム・ホストと呼ばれる) では、呼び出し元は、結合先のインターフェースを選択することができます。次に、(結合された名前と一致する) このインターフェースからの UDP パケットおよび TCP 接続要求だけが、アプリケーションに転送されます。netinet/in.h で定義したように、このフィールドを定数 INADDR_ANY に設定すると、呼び出し元は、ホスト上のすべてのネットワーク・インターフェースにソケットが結合されるよう要求します。続いて、(結合された名前と一致する) すべての インターフェースからの UDP パケットおよび TCP 接続が、アプリケーションに転送されます。サーバーが複数のネットワークにサービスを提供する ときには、この方法が重要です。アドレスを未指定のままにすることにより、サーバーは、要求の到達先のネットワーク・インターフェースにかかわらず、そのポート用に作成された UDP パケットおよび TCP 接続要求 をすべて受け入れることができます。
sin_zero フィールドは使用されません。また、このフィールド は、すべてゼロに設定する必要があります。
struct sockaddr_in6 {
uint8_t sin6_len;
sa_family_t sin6_family;
in_port_t sin6_port;
uint32_t sin6_flowinfo;
struct in6_addr sin6_addr;
uint32_t sin6_scope_id;
};
sin6_len フィールドは、この構造体のサイズにセットされます。 SIN6_LEN マクロは、使用されている sockaddr_in6 構造体のバージョンを表すように定義されています。
sin6_family フィールドは、これを sockaddr_in6 構造体と識別します。 このフィールドは、バッファーが sockaddr 構造体にキャストされた時に sa_family フィールドをオーバーレイします。このフィールドの値は、AF_INET6 でなければなりません。
sin6_port フィールドは、16 ビット UDP または TCP ポート番号を含んでいます。 このフィールドは、sockaddr_in 構造体の sin_port フィールドと同じ方法で使用されます。ポート番号は、ネットワーク・バイト順に保管されます。
sin6_flowinfo フィールドは、32 ビットのフィールドで、トラフィック・クラスとフロー・ラベルを含んでいます。
sin6_addr フィールドは、単一の in6_addr 構造体です。このフィールドは、 1 つの 128 ビット IPv6 アドレスを保持しています。アドレスは、ネットワーク・バイト順に保管されます。
sin6_scope_id フィールドは、32 ビットの整数で、sin6_addr フィールドに繰り上がったアドレスのスコープに見合ったインターフェースのセットを示します。これは、リンク・スコープ sin6_addr、sin6_scope_id のインターフェース・インデックスです。これは、サイト・スコープ sin6_addr、sin6_scope_id のサイト ID です。
AF_UNIX ドメインで作成されたソケット記述子
struct sockaddr_un {
unsigned char sun_len;
unsigned char sun_family;
char sun_path[108]; /* pathname */
};
sun_family フィールドは、AF_UNIX に設定します。
- AF_UNIX の場合、結合が発行されると、660 のモードでファイル が作成されます。他のユーザーがこのファイルにアクセスできるようにする には、chmod() を発行し、必要に応じてこのモードを変更してください。
- AF_UNIX の場合には、結合されたソケットのクローズの際に 、unlink() も使用して、bind() 時に作成 されたファイルを削除する必要があります。
- クライアントが bind() で使用するパス名は固有でなければ なりません。
- sendto() 呼び出しには、サーバーに関連したパス名を 指定しなければなりません。
- AF_INET または AF_INET6 の場合、ユーザーは、1 ~ 1023 までの範囲のポートにバインドするために、適切な特権を持っている必要があります。
C++ の特殊な動作
この関数を C++ で使用するには、_XOPEN_SOURCE_EXTENDED 1 フィーチャー・テスト・マクロを使用する必要があります。
戻り値
正常に実行された場合、bind() は、0 を戻します。
- エラー・コード
- 説明
- EACCES
- 許可が拒否されました。
- EADDRINUSE
- アドレスは既に使用中である。詳細は、getsockopt() - ソケットに関連したオプションの取得で説明して いる SO_REUSEADDR オプション、および setsockopt() - ソケットに関連したオプションの設定で説明して いる SO_REUSEADDR オプションを参照します。
- EADDRNOTAVAIL
- 指定されたアドレスがこのホストでは無効である。例えば、IP アドレスが有効な ネットワーク・インターフェースを指定していません。
- EAFNOSUPPORT
- アドレス・ファミリーはサポートされていません (それは AF_UNIX、AF_INET、または AF_INET6 ではありません)。
- EBADF
- socket パラメーターが無効ソケット記述子です。
- EINVAL
- 次の 3 つの状態のいずれかが当てはまる可能性があります。
- ソケットが既にアドレスに結合済みです。例えば、既に 接続済みのソケットに名前を結合しようとしています。
- ソケットがシャットダウンされました。
- bind() 呼び出しで正しくないパラメーターが渡されました。
- EIO
- ネットワークまたはトランスポートで障害が発生しました。
- ENOBUFS
- bind() は、ストレージが不十分なためにバッファーを取得することができません。
- ENOTSOCK
- 記述子はファイル用であり、ソケット用ではありません。
- EOPNOTSUPP
- 指定されたソケットのソケット・タイプが アドレスへの結合をサポートしません。
- EPERM
- ユーザーは、指定されたポートへの結合を 許可されていません。
- エラー・コード
- 説明
- EACCES
- パス接頭部のコンポーネントが検索許可を拒否します。あるいは、要求された名前が、書き込み許可を拒否するモードで ディレクトリーへの書き込みを要求します。
- EDESTADDRREQ
- address 引数が NULL ポインターです。
- EIO
- 入出力エラーが発生しました。
- ELOOP
- address のパス名の変換中に検出された シンボリック・リンクが多すぎます。
- ENAMETOOLONG
- パス名のコンポーネントが NAME_MAX 文字を超えたか、あるいはパス名全体が PATH_MAX 文字を超えました。
- ENOENT
- パス名のコンポーネントに既存のファイル名が指定されていないか、またはパス名が空ストリングです。
- ENOTDIR
- address のパス名のパス接頭部のコンポーネントが ディレクトリーではありません。
- EROFS
- 名前が読み取り専用ファイル・システム上にあります。
例
以下に示すのは、bind() 呼び出しの例です。要求された名前が予約済みフィールドを何も設定しない ようにするため、構造体を使用する前に構造体をゼロに するのは適切な方法です。
AF_INET ドメインの例
int rc;
int s;
struct sockaddr_in myname;
/* Bind to a specific interface in the Internet domain */
/* make sure the sin_zero field is cleared */
memset(&myname, 0, sizeof(myname));
myname.sin_family = AF_INET;
myname.sin_addr.s_addr = inet_addr("129.5.24.1");
/* specific interface */
myname.sin_port = htons(1024);
⋮
rc = bind(s, (struct sockaddr *) &myname,
sizeof(myname));
/* Bind to all network interfaces in the Internet domain */
/* make sure the sin_zero field is cleared */
memset(&myname, 0, sizeof(myname));
myname.sin_family = AF_INET;
myname.sin_addr.s_addr = INADDR_ANY; /* specific interface */
myname.sin_port = htons(1024);
⋮
rc = bind(s, (struct sockaddr *) &myname,
sizeof(myname));
/* Bind to a specific interface in the Internet domain.
Let the system choose a port */
/* make sure the sin_zero field is cleared */
memset(&myname, 0, sizeof(myname));
myname.sin_family = AF_INET;
myname.sin_addr.s_addr = inet_addr("129.5.24.1");
/* specific interface */
myname.sin_port = 0;
⋮
rc = bind(s, (struct sockaddr *) &myname,
sizeof(myname));
AF_UNIX ドメインの例
/* Bind to a name in the UNIX domain */
struct sockaddr_un myname;
char socket_name[]="/tmp/socket.for._";
⋮
memset(&myname, 0, sizeof(myname));
myname.sun_family = AF_UNIX;
strcpy(myname.sun_path,socket_name);
myname.sun_len = sizeof(myname.sun_path);
⋮
rc = bind(s, (struct sockaddr *) &myname, SUN_LEN(&myname));