BIND(2) | Linux Programmer's Manual | BIND(2) |
名前¶
bind - ソケットに名前をつける
書式¶
#include <sys/types.h> /* 「注意」参照 */ #include <sys/socket.h> int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
説明¶
socket(2) でソケットが作成されたとき、そのソケットは名前空間 (アドレス・ファミリー) に 存在するが、アドレスは割り当てられていない。 bind() は、ファイルディスクリプタ sockfd で参照されるソケットに addr で指定されたアドレスを割り当てる。 addrlen には addr が指すアドレス構造体のサイズをバイト単位で指定する。 伝統的にこの操作は 「ソケットに名前をつける」 と呼ばれる。
SOCK_STREAM ソケットが接続を受け付けられるようにするには (accept(2) を参照)、通常その前に bind() を使用してローカルアドレスを割り当てる必要がある。
名前付けのルールはアドレス・ファミリーごとに異なっている。詳細な情報は 第 7 章の各マニュアルを参照すること。 AF_INET は ip(7) を、 AF_INET6 は ipv6(7) を、 AF_UNIX は unix(7) を、 AF_APPLETALK は ddp(7) を、 AF_PACKET は packet(7) を、 AF_X25 は x25(7) を、 AF_NETLINK は netlink(7) を参照。
addr
引き数に実際にどのような構造体が渡されるかは、
アドレス・ファミリーに依存する。
sockaddr
構造体は以下のような感じで定義されている:
struct sockaddr {
sa_family_t sa_family;
char sa_data[14]; }
この構造体は、 addr に渡される構造体へのポインタをキャストし、 コンパイラの警告メッセージを抑えるためだけに存在する。 下記の「例」を参照。
返り値¶
成功すると 0 を返す。 失敗すると -1 を返し、 errno を適切に設定する。
エラー¶
- EACCES
- そのアドレスは保護されていて、かつユーザがスーパーユーザではない。
- EADDRINUSE
- 指定されたアドレスが既に使用中である。
- EBADF
- sockfd が不正なディスクリプタである。
- EINVAL
- ソケットがすでにアドレスに結びつけ (bind) られている。 ENOTSOCK sockfd がファイルに対するディスクリプタで、ソケットに対するものではない。
以下のエラーは Unixドメイン (AF_UNIX) のソケット特有である:
- EACCES
- パス名の構成要素に検索許可 (search permission) がない (path_resolution(7) も参照すること)。
- EADDRNOTAVAIL
- 存在しないインタフェースが要求されたか、要求されたアドレスが ローカルではなかった。
- EFAULT
- addr がユーザのアクセス可能なアドレス空間の外を指している。
- EINVAL
- addrlen が不正であるか、ソケットが AF_UNIX ファミリーではない。
- ELOOP
- addr を解決する際に遭遇したシンボリック・リンクが多過ぎる。
- ENAMETOOLONG
- addr が長過ぎる。
- ENOENT
- ファイルが存在しない。
- ENOMEM
- カーネルに、利用可能なメモリーが十分にない。
- ENOTDIR
- パス名の構成要素がディレクトリではない。
- EROFS
- ソケット inode が読み込み専用のファイルシステム上にある。
準拠¶
SVr4, 4.4BSD, POSIX.1-2001 (bind() は 4.2BSD で最初に現われた)。
注意¶
POSIX.1-2001 では <sys/types.h> のインクルードは必須とされておらず、 Linux ではこのヘッダファイルは必要ではない。 しかし、歴史的には、いくつかの実装 (BSD 系) でこのヘッダファイルが 必要であり、移植性が必要なアプリケーションではこのファイルを インクルードするのが賢明であろう。
bind() の三番目の引き数は (4.x BSD や libc4, libc5 と同様に) 実際には int である。glibc でも使われている現在の socklen_t に関して、POSIX には少し混乱がある。 詳しくは accept(2) を参照のこと。
バグ¶
透過的プロキシ (transparent proxy) オプションについて記述していない。
例¶
インターネット・ドメイン・ソケットでの bind() の利用例が getaddrinfo(3) に記載されている。
以下の例は、Unix ドメイン (AF_UNIX) でストリームソケットを bind する方法を示したものである。
#include <sys/socket.h> #include <sys/un.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #define MY_SOCK_PATH "/somepath" #define LISTEN_BACKLOG 50 #define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0) int main(int argc, char *argv[]) {
int sfd, cfd;
struct sockaddr_un my_addr, peer_addr;
socklen_t peer_addr_size;
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sfd == -1)
handle_error("socket");
memset(&my_addr, 0, sizeof(struct sockaddr_un));
/* Clear structure */
my_addr.sun_family = AF_UNIX;
strncpy(my_addr.sun_path, MY_SOCK_PATH,
sizeof(my_addr.sun_path) - 1);
if (bind(sfd, (struct sockaddr *) &my_addr,
sizeof(struct sockaddr_un)) == -1)
handle_error("bind");
if (listen(sfd, LISTEN_BACKLOG) == -1)
handle_error("listen");
/* Now we can accept incoming connections one
at a time using accept(2) */
peer_addr_size = sizeof(struct sockaddr_un);
cfd = accept(sfd, (struct sockaddr *) &peer_addr,
&peer_addr_size)
if (cfd == -1)
handle_error("accept");
/* Code to deal with incoming connection(s)... */
/* When no longer required, the socket pathname, MY_SOCK_PATH
should be deleted using unlink(2) or remove(3) */ }
関連項目¶
accept(2), connect(2), getsockname(2), listen(2), socket(2), getaddrinfo(3), getifaddrs(3), ip(7), ipv6(7), path_resolution(7), socket(7), unix(7)
2007-12-28 | Linux |