Provided by: manpages-ja-dev_0.5.0.0.20210215+dfsg-1_all
名前
recv, recvfrom, recvmsg - ソケットからメッセージを受け取る
書式
#include <sys/types.h> #include <sys/socket.h> ssize_t recv(int sockfd, void *buf, size_t len, int flags); ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
説明
recv(), recvfrom(), recvmsg() コールは、 ソケットからメッセージを受け取るのに使用される。 これらはコネクションレス型のソケットにも接続指向 (connection-oriened) 型のソケットにも使用 できる。 このページでは、まずこれら 3 つのシステムコールすべてに共通の機能について説明し、 システムコール間の違いについて説明する。 これらの三つのシステムコールはいずれも、成功した場合にはメッセージの長さを返す。 メッセー ジが長過ぎて指定されたバッファーに入り切らなかった場合には、 メッセージを受信したソケット の種類によっては余分のバイトが捨てられる かもしれない。 ソケットに受け取るメッセージが存在しなかった場合、 受信用のコールはメッセージが到着するま で待つ。 ただし、ソケットが非停止 (nonblocking) に設定されていた場合 (fcntl(2) を参照) は -1 を返し、外部変数 errno に EAGAIN か EWOULDBLOCK を設定する。 これらの受信用のコール は、受信したデータのサイズが要求したサイズに 達するまで待つのではなく、何らかのデータを受 信すると復帰する (受信されるデータの最大サイズは要求したサイズである)。 アプリケーションは select(2), poll(2), epoll(7) を使って、ソケットにさらにデータが到着して いるかを判定することができる。 フラグ引き数 flags 引き数には、以下の値を 1つ以上、ビット単位の論理和 を取ったものを指定する: MSG_CMSG_CLOEXEC (recvmsg() のみ; Linux 2.6.23) (unix(7) で説明されている) SCM_RIGHTS 操作を使って UNIX ドメインのファイルディス クリプター経由で受信した ファイルディスクリプターについて close-on-exec フラグを セットする。 このフラグは、 open(2) の O_CLOEXEC フラグと同じ理由で有用である。 MSG_DONTWAIT (Linux 2.2 以降) 非停止 (nonblocking) 操作を有効にする。 操作が停止するような場合にエラー EAGAIN か EWOULDBLOCK で呼び出しが失敗する (fcntl(2) の F_SETFL で O_NONBLOCK フラグを指定す ることによっても有効にできる)。 MSG_ERRQUEUE (Linux 2.2 以降) このフラグを指定すると、 キューに入れられたエラーをソケットのエラーキューから取りだ せるようになる。 このエラーは補助メッセージに組み込まれて渡され、 この補助メッセー ジの種別はプロトコルに依存する (IPv4 の場合は IP_RECVERR)。 ユーザーは十分なサイズ のバッファーを用意しなければならない。 補助メッセージに関するより詳細な情報は cmsg(3) および ip(7) を参照のこと。 エラーの原因となったオリジナルパケットのペイ ロードは、 msg_iovec 経由で通常のデータとして渡される。 エラーを起こしたデータグラ ムのオリジナルの宛先アドレスは、 msg_name 経由で参照できる。 ローカルなエラーの場合はアドレスは渡されない (これは cmsghdr の cmsg_len メンバーで チェックできる)。 受信エラーの場合は MSG_ERRQUIE が msghdr にセットされる。 エラー が渡された後には、キューに入っている次のエラーに基いて、 処理待ちのソケットエラーが 再生成され、次のソケット操作の際に渡される。 このエラーは sock_extended_err 構造体で提供される: #define SO_EE_ORIGIN_NONE 0 #define SO_EE_ORIGIN_LOCAL 1 #define SO_EE_ORIGIN_ICMP 2 #define SO_EE_ORIGIN_ICMP6 3 struct sock_extended_err { uint32_t ee_errno; /* error number */ uint8_t ee_origin; /* where the error originated */ uint8_t ee_type; /* type */ uint8_t ee_code; /* code */ uint8_t ee_pad; /* padding */ uint32_t ee_info; /* additional information */ uint32_t ee_data; /* other data */ /* More data may follow */ }; struct sockaddr *SO_EE_OFFENDER(struct sock_extended_err *); ee_errno にはキューに入れられたエラーの errno が入っている。 ee_origin にはエラーが 発生した場所のオリジンコード (origin code) が入っている。 他のフィールドはプロトコ ル依存である。 SO_EE_OFFENDER マクロは、この補助的なメッセージを引き数に取って、 エ ラーの発生したネットワークオブジェクトのアドレスへのポインターを返す。 アドレスが不 明の場合には、 sockaddr の sa_family メンバーが AF_UNSPEC になっている。 sockaddr の他のフィールドは不定である。 エラーの発生したパケットのペイロードは通常のデータと して渡される。 ローカルなエラーの場合はアドレスは渡されない (これは cmsghdr の cmsg_len メンバーで チェックできる)。 受信エラーの場合は MSG_ERRQUIE が msghdr にセットされる。 エラー が渡された後には、キューに入っている次のエラーに基いて、 処理待ちのソケットエラーが 再生成され、次のソケット操作の際に渡される。 MSG_OOB このフラグは、通常のデータストリームでは受信できない 帯域外 (out-of-band) データの 受信を要求する。 プロトコルによっては、 通常のデータキューの先頭に速達データを置く ものがあるが、 そのようなプロトコルではこのフラグは使用できない。 MSG_PEEK このフラグを指定すると、 受信キューの最初のデータを返すとき、キューからデータを削除 しない。 したがって、この後でもう一度受信コールを呼び出すと、同じデータが返ることに なる。 MSG_TRUNC (Linux 2.2 以降) raw ソケット (AF_PACKET)、 Internet datagram ソケット (Linux 2.4.27/2.6.8 以降)、 netlink (Linux 2.6.22 以降) ソケット、 UNIX datagram ソケット (Linux 3.4 以降) の場 合、パケットやデータグラムの長さが渡したバッファーよりも長かった場合にも、 パケット やデータグラムの実際の長さを返す。 Internet ストリームソケットでの利用については tcp(7) を参照。 MSG_WAITALL (Linux 2.2 以降) このフラグは、要求した量いっぱいのデータが到着するまで、 操作を停止 (block) するよ う要求する。 但し、シグナルを受信したり、エラーや切断 (disconnect) が発生したり、 次に受信されるデータが異なる型だったりした場合には、 要求した量よりデータが少なくて も返ることがある。 recvfrom() recvfrom() は受信したメッセージをバッファー buf に格納する。 呼び出し元はバッファーサイズ を len で指定しなければならない。 src_addr が NULL 以外で、下層のプロトコルからメッセージの送信元アドレスが分かる場合、 この 送信元アドレスが src_addr が指すバッファーに格納される。 この場合、 addrlen は入出力両用の 引き数となる。 呼び出し前に、呼び出し元は src_addr に割り当てたバッファーの大きさで初期化 しておくべきである。 返ってくる時には、 addrlen は送信元アドレスの実際の大きさに変更され る。渡されたバッファーが小さ過ぎる場合には、返されるアドレスの末尾は 切り詰められる。この 場合には、 addrlen では、呼び出し時に渡された値よりも大きな値が返される。 呼び出し元が送信元アドレスを必要としない場合は、 src_addr と addrlen には NULL を指定すべ きである。 recv() recv() コールは通常 接続済みの (connected) ソケットに対してのみ使用される (connect(2) 参 照)。次の呼び出しと等価である。 recvfrom(fd, buf, len, flags, NULL, 0)); recvmsg() recvmsg() コールは、直接渡す引き数の数を減らすために msghdr 構造体を使用する。この構造体 は <sys/socket.h> で以下のように定義されている: struct iovec { /* Scatter/gather array items */ void *iov_base; /* Starting address */ size_t iov_len; /* Number of bytes to transfer */ }; struct msghdr { void *msg_name; /* 追加のアドレス */ socklen_t msg_namelen; /* アドレスのサイズ */ struct iovec *msg_iov; /* scatter/gather 配列 */ size_t msg_iovlen; /* msg_iov の要素数 */ void *msg_control; /* 補助データ (後述) */ size_t msg_controllen; /* 補助データバッファー長 */ int msg_flags; /* 受信メッセージのフラグ */ }; フィールド msg_name は、 ソケットが接続されていない場合に送信元アドレスを返すのに使用され るバッファーを指す。 このバッファーは呼び出し元が確保する。 呼び出し元は呼び出し前に msg_namelen にこのバッファーの大きさを設定しなければならない。 呼び出しが成功した場合、呼 び出しから返って来た際には msg_namelen には返されるアドレスの長さが入っている。 アプリケー ションが送信元アドレスを知る必要がない場合には、 msg_name に NULL を指定することができる。 msg_iov と msg_iovlen フィールドは scatter-gather 用の場所を指定する。 readv(2) に説明があ る。 msg_control フィールドは msg_controllen の長さを持ち、他のプロトコル制御メッセージや 種々の補助データのためのバッファーへのポインターである。 recvmsg() を呼ぶ際には、 msg_controllen に msg_control のバッファーの長さを入れておく必要がある。 コールが成功して 返った場合、制御メッセージ列の長さが入っている。 メッセージの形式は以下の通り: struct cmsghdr { socklen_t cmsg_len; /* data byte count, including hdr */ int cmsg_level; /* originating protocol */ int cmsg_type; /* protocol-specific type */ /* followed by unsigned char cmsg_data[]; */ }; 補助データは、 cmsg(3) に定義されたマクロ経由でのみアクセスすべきである。 例をあげると、 Linux はこの補助データのメカニズムを、 UNIX ドメインソケット上での拡張エ ラーや IP オプション、 ファイルディスクリプターの受け渡しに利用している。 msghdr の msg_flags フィールドは recvmsg() からのリターン時に設定される。ここにはいくつか のフラグが入る。 MSG_EOR これはレコードの終り (end-of-record) を示し、 返されたデータが完全なレコードである ことを示す (一般的には SOCK_SEQPACKET 型のソケットで使用される)。 MSG_TRUNC データグラムが与えられたバッファーより大きかったために、 データグラムのはみ出した部 分が捨てられたことを示す。 MSG_CTRUNC 補助データのためのバッファーが不足したために、 制御データの一部が捨てられたことを示 す。 MSG_OOB 速達データや帯域外データを受信したことを示す。 MSG_ERRQUEUE データは受信しなかったが ソケットのエラーキューから拡張エラーを受信したことを示す。
返り値
これらのコールは受信したバイト数を返す。 エラーの場合は -1 を返し、 errno にエラーを示す値 を設定する。 ストリームソケットの接続相手が正しくシャットダウンを実行した場合は、 返り値は 0 (昔ながら の "end-of-file" の戻り値) となる。 いくつかのドメインのデータグラムソケット (UNIX ドメインやインターネットドメインなど) で は、長さ 0 のデータグラムが送信できる。 このようなデータグラムを受信した場合、 返り値は 0 となる。 ストリームソケットに対する受信要求バイト数が 0 だった場合も、 値 0 が返される。
エラー
これらはソケット層で発生する一般的なエラーである。 他のエラーが下層のプロトコルモジュール で生成され、 返されるかもしれない。 それらのマニュアルを参照すること。 EAGAIN または EWOULDBLOCK ソケットが非停止 (nonblocking) に設定されていて 受信操作が停止するような状況になっ たか、 受信に時間切れ (timeout) が設定されていて データを受信する前に時間切れになっ た。 POSIX.1-2001 は、この場合にどちらのエラーを返すことも認めており、 これら 2 つ の定数が同じ値を持つことも求めていない。 したがって、移植性が必要なアプリケーション では、両方の可能性を 確認すべきである。 EBADF 引き数 sockfd が不正なディスクリプターである。 ECONNREFUSED リモートのホストでネットワーク接続が拒否された (よくある理由としては、要求したサー ビスが起動されていないなどがある)。 EFAULT 受信バッファーへのポインターがプロセスのアドレス空間外を指している。 EINTR データを受信する前に、シグナルが配送されて割り込まれた。 signal(7) 参照。 EINVAL 不正な引き数が渡された。 ENOMEM recvmsg() のためのメモリーが確保できなかった。 ENOTCONN ソケットに接続指向プロトコルが割り当てられており、 まだ接続されていない (connect(2) と accept(2) を参照のこと)。 ENOTSOCK 引き数 sockfd がソケットを参照していない。
準拠
4.4BSD (これらの関数は 4.2BSD で現われた), POSIX.1-2001。 POSIX.1-2001 では、 MSG_OOB, MSG_PEEK, MSG_WAITALL フラグだけが記載されている。
注意
socklen_t 型は POSIX で発案された。 accept(2) も参照。 POSIX.1-2001 では、構造体 msghdr のフィールド msg_controllen は socklen_t 型であるべきだと されているが、 現在の glibc では size_t 型である。 recvmmsg(2) には、一度の呼び出しでの複数のデータグラムに使用できる Linux 固有の システム コールに関する情報が書かれている。
例
recvfrom() の利用例が getaddrinfo(3) に記載されている。
関連項目
fcntl(2), getsockopt(2), read(2), recvmmsg(2), select(2), shutdown(2), socket(2), cmsg(3), sockatmark(3), socket(7)
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクト の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。