RECV(2)

名前
recv, recvfrom, recvmsg - ソケットからメッセージを受け取る

書式
#include <sys/types.h>
#include <sys/socket.h>

int recv(int s, void *buf, int len, unsigned int flags);

int recvfrom(int s, void *buf, int len, unsigned int flags struct sockaddr *from, int *fromlen);

int recvmsg(int s, struct msghdr *msg, unsigned int flags);

説明
recvfrom と recvmsg はソケットからメッセージを受け取るのに使用し、ソケットが接続指向 (connection-oriened)であってもなくてもソケットのデータを受信する ことができる。 from が NULL でなく、ソケットが接続指向でない場合、 from にメッセージの送信元のアドレスが入れられる。 fromlen は入出力両用のパラメーターで、最初は from に割り当てたバッファーの大きさを入れておき、返ってくる時には from に実際に入れアドレスの大きさに修正されて返される。 recv コールは通常 接続された(connected) ソケット( connect(2) を参照)についてのみ使用され、 from パラメーターが NULL の recvfrom と等価である。 冗長であるため、将来のリリースではサポートされないかもしれない。 成功した場合には三つのルーチンはメッセージの長さを返す。 メッセージ長過ぎて与えられたバッファーに納まらなかった場合には メッセージを受信したソケットの種類によっては余分のバイトは捨てられる かもしれない。( socket(2) を参照)。 ソケットに受け取るメッセージが存在しなかった場合、受信用のコールは メッセージが到着するまで待つ。ただしソケットが非停止(nonblocking) に設定されていた場合( fcntl(2) を参照)は -1 を返し外部変数 errno に EWOULDBLOCK が設定される。 受信コールは通常、要求した最大量以下で受信したデータを返し、 要求量いっぱいまで受信するまで待つことはない。この動作は getsockopt(2) に記述されたソケット層のオプション SO_RCVLOWAT と SO_RCVTIMEO の影響を受ける。 select(2) コールはいつデータが届くかを決定するために使用できる。 recv コールの flags 引き数は以下の値の一つ以上の or である:

MSG_OOB
    帯域外(out-of-band)データを処理する

MSG_PEEK
    入って来たメッセージを調べる

MSG_WAITALL
    要求を完全に満すかエラーが起こるまで待つ MSG_OOB フラグは通常のデータ・ストリームで受信できない帯域外(out-of-band)データを 受信することを要求する。通常のデータ・キューの先頭に速達データを置く プロトコルも存在する、それでそのようなプロトコルではこのフラグは 使用できない。 MSG_PEEK フラグは受信キューの最初のデータをキューからデータを削除せずに返す。 これによって続く受信コールで同じデータを返すことができる。 MSG_WAITALL フラグは要求した量を完全に満すまで操作を停止(block)することを要求する。 しかしながら、シグナルを受信したり、エラーや切断(disconnect)が起ったり 次に受信したデータが異る型だった場合には、要求した量より少ないデータを 返すことがある。 recvmsg コールは直接与えるパラメーターの数を減らすために msghdr 構造体を使用する。この構造体は sys/socket.h で以下のように定義されている :
    struct msghdr {
    	caddr_t	msg_name;	/* optional address */
    	u_int	msg_namelen;	/* size of address */
    	struct	iovec *msg_iov;	/* scatter/gather array */
    	u_int	msg_iovlen;	/* # elements in msg_iov */
    	caddr_t	msg_control;	/* ancillary data, see below */
    	u_int	msg_controllen; /* ancillary data buffer len */
    	int	msg_flags;	/* flags on received message */
    };
ここで msg_name と msg_namelen はソケットが接続されていない場合に、相手のアドレスが格納される。 名前が必要ない場合には msg_name に NULL を入れることができる。 msg_iov と msg_iovlen は readv(2) に記述されているような送信/送信用のベクターを指定する。 msg_control, は msg_controllen の長さを持ち、他のメッセージ関連のプロトコルを制御するバッファーや 他の補助的なデータのためのバッファーへのポインターである。 メッセージの形式は:
    struct cmsghdr {
    	u_int	cmsg_len;	/* data byte count, including hdr */
    	int	cmsg_level;	/* originating protocol */
    	int	cmsg_type;	/* protocol-specific type */
    /* followed by
    	u_char	cmsg_data[]; */
    };
例えば、この構造体から XNS/SPP や ISO においてデータ・ストリームの 変化を知ることができる。 accept コールの直後に recvmsg をデータ・バッファーをなしで呼ぶことにより、 この構造体に「ユーザー接続要求(user-connection-request)」を 取得することができる。 オープンされたファイル・ディスクリプターは補助的なデータとして AF_UNIX ドメイン・ソケットに渡され、 cmsg_level に SOL_SOCKET が設定され、 cmsg_type に SCM_RIGHTS が設定される。 msg_flags フィールドは受信したメッセージを参照するように返却時に設定される。 MSG_EOR はレコードの終り(end-of-record)を示し、そのデータは完全なレコードを 返したことを示す(一般的には SOCK_SEQPACKET 型のソケットで使用される)。 MSG_TRUNC は、データグラムが与えられたバッファーより大きかったために データグラムのはみ出した部分が捨てられたことを示す。 MSG_CTRUNC は補助的なデータのためのバッファーが不足したために制御データの一部が 捨てらてらこを示す。 速達データや帯域外データを受信したことを示すために MSG_OOB が返される。

返り値
これらのコールは受信したバイト数を返す。エラーの場合は -1 が返される。

エラー

EBADF
    引き数 s が無効なディスクリプターである。

ENOTCONN
    ソケットに接続指向プロトコルが割り当てられており、 まだ接続されていない。( connect(2) と accept(2) を参照すること)。

ENOTSOCK
    引き数 s がソケットを参照していない。

EWOULDBLOCK
    ソケットが非停止(non-blocking)に設定されており受信操作が停止したか、 受信に時間切れ(timeout)が設定されおり、データを受信する前に 時間切れになった。

EINTR
    データを受信する前にシグナル(signal)が配送されて割り込まれた。

EFAULT
    受信バッファーへのポインターがプロセスのアドレス空間外を指している。

準拠
4.4BSD (これらの関数は 4.2BSD で現われた)。

関連項目
fcntl(2), read(2), select(2), getsockopt(2), socket(2)