bind

Autres langues

Langue: ja

Version: 2007-06-08 (fedora - 25/11/07)

Section: 2 (Appels système)

名前

bind - ソケットに名前をつける

書式

 #include <sys/types.h>          /* 「注意」参照 */
 #include <sys/socket.h>
 
 int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen);
 

説明

bind() はソケット sockfd にローカルアドレス my_addr を割り当てる。 my_addraddrlen バイトの長さである。 伝統的にこの処理は 「ソケットに名前をつける」 と呼ばれる。 socket(2) でソケットが作成されたとき、 ソケットは名前空間 (アドレス・ファミリー) に存在するが、 名前はつけられていない。

SOCK_STREAM ソケットが接続を受け付けられるようにするには (accept(2) を参照)、通常その前に bind() を使用してローカルアドレスを割り当てる必要がある。

名前付けのルールはアドレス・ファミリーごとに異なっている。詳細な情報は 第 7 章の各マニュアルを参照すること。 AF_INETip(7) を、 AF_INET6ipv6(7) を、 AF_UNIXunix(7) を、 AF_APPLETALKddp(7) を、 AF_PACKETpacket(7) を、 AF_X25x25(7) を、 AF_NETLINKnetlink(7) を参照。

my_addr 引き数に実際にどのような構造体が渡されるかは、 アドレス・ファミリーに依存する。 sockaddr 構造体は以下のような感じで定義されている:

 
 struct sockaddr {
     sa_family_t sa_family;
     char        sa_data[14];
 }
 
 
この構造体は、 my_addr に渡される構造体へのポインタをキャストし、 コンパイラの警告メッセージを抑えるためだけに存在する。 下記の「例」を参照。

返り値

成功すると 0 を返す。 失敗すると -1 を返し、 errno を適切に設定する。

エラー

EACCES
そのアドレスは保護されていて、かつユーザがスーパーユーザではない。
EADDRINUSE
指定されたアドレスが既に使用中である。
EBADF
sockfd が不正なディスクリプタである。
EINVAL
ソケットがすでにアドレスに結びつけ (bind) られている。 ENOTSOCK sockfd がファイルに対するディスクリプタで、ソケットに対するものではない。

以下のエラーは UNIXドメイン (AF_UNIX) のソケット特有である:

EACCES
パス名の構成要素に検索許可 (search permission) がない (path_resolution(7) も参照すること)。
EADDRNOTAVAIL
存在しないインタフェースが要求されたか、要求されたアドレスが ローカルではなかった。
EFAULT
my_addr がユーザのアクセス可能なアドレス空間の外を指している。
EINVAL
addrlen が不正であるか、ソケットが AF_UNIX ファミリーではない。
ELOOP
my_addr を解決する際に遭遇したシンボリック・リンクが多過ぎる。
ENAMETOOLONG
my_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 die(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)
         die("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)
         die("bind");
     
     if (listen(sfd, LISTEN_BACKLOG) == -1)
         die("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)
         die("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), ip(7), ipv6(7), path_resolution(7), socket(7), unix(7)