スポンサーリンク

RECV(2) FreeBSD システムコールマニュアル RECV(2)

名称

recv, recvfrom, recvmsg − ソケットからメッセージを受信する

ライブラリ

標準 C ライブラリ (libc, −lc)

書式

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

ssize_t

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

ssize_t

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

ssize_t

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

解説

recvfrom() と recvmsg() システムコールは、ソケットからのメッセージを受信 するのに使用されます。ソケットが接続指向であるかどうかにかかわらず、ソ ケット上のデータを受信するのに使用できます。

from が NULL ポインタでなく、ソケットが接続指向でない場合、ここにはメッ セージのソースアドレスが保存されます。 fromlen 引数は値と結果の引数であ り、 from に対応するバッファのサイズに初期化され、戻り時には保存されたア ドレスの実際のサイズを示すように変更されます。

recv() システムコールは、通常 接続されたソケット上だけで使用され (connect(2) を参照)、 from 引数に NULL ポインタを指定した recvfrom() と同 一です。これは冗長なので、将来のリリースではサポートされない可能性があり ます。

これら 3 つのルーチンは正常に完了するとメッセージの長さを返します。メッ セージが長すぎて指定のバッファに収まらない場合、メッセージを受信したソ ケットのタイプによっては超過分のバイトが破棄されることがあります (socket(2) を参照)。

ソケットにメッセージが無い場合は、ソケットが非ブロッキング (fcntl(2) を参 照) の場合を除き、呼び出しはメッセージが到着するのを待ちます。ソケットが 非ブロッキングの場合、値 -1 が返され、外部変数 errno が EAGAIN に設定され ます。通常、受信呼び出しは要求された量を受信するまで待たずに、要求された 量を上限として得られたデータを返します。この動作は、 getsockopt(2) で解説 されているソケットレベルのオプション SO_RCVLOWAT および SO_RCVTIMEO に よって影響を受けます。

次のデータがいつ到着するかを判定するには select(2) システムコールを使うこ とができます。

recv() 関数への flags 引数は、次の値の 1 つまたは複数の論理和 (or) から成 ります:

MSG_OOB プロセス帯域外データ
MSG_PEEK 着信メッセージの覗き見 (peek)
MSG_WAITALL 要求の完全な実行、またはエラーを待つ
MSG_DONTWAIT ブロックしない

MSG_OOB フラグは帯域外データの受信を要求し、通常のデータストリームからは 受信しません。急送データを通常のデータ待ち行列の先頭に配置するプロトコル もありますが、このフラグはそのようなプロトコルでは使用できません。 MSG_PEEK フラグは受信待ち行列の先頭からデータを除去することなく、そのデー タを返します。したがって、後続の受信呼び出しは同じデータを返します。 MSG_WAITALL フラグは要求が完全に満たされるまでブロックするように要求しま す。しかし、シグナルが捕捉された場合、エラーまたは切断が発生した場合、ま たは受信する次のデータが返されたタイプと異なる場合、呼び出しは要求された より少ないデータを返す可能性があります。 MSG_DONTWAIT フラグは、フラグが 指定されてなかったらブロックするような時に、戻ることを要求します。利用可 能なデータが無い場合には、 errno が EAGAIN に設定されます。このフラグは、 厳格な ANSI または C99 のコンパイルモードでは利用できません。

recvmsg() システムコールは、直接に指定される引数の数を最小にするために msghdr 構造体を使用します。この構造体は <sys/socket.h> で定義されているよ うに、次の形式になっています:

struct msghdr {

caddr_t

msg_name;

/* アドレス (オプション) */

u_int

msg_namelen;

/* アドレスのサイズ */

struct

iovec *msg_iov;

/* スキャッタ / ギャザー配列 */

u_int

msg_iovlen;

/* msg_iov の要素数 */

caddr_t

msg_control;

/* 補助データ、後述 */

u_int

msg_controllen; /* 補助データのバッファ長 */

int

msg_flags;

/* 受信されたメッセージ上のフラグ */

};

ここで msg_namemsg_namelen は、ソケットが接続されていない場合に、宛先 アドレスを指定します。名前を要求しない場合や必要でない場合、 msg_name は NULL ポインタとして指定できます。 msg_iovmsg_iovlen 引数は read(2) で 説明されているようにスキャッタ / ギャザーの場所を記述します。 msg_control 引数は、長さが msg_controllen の、他のプロトコル制御に関連するメッセージ またはその他の各種補助データ用のバッファを指しています。メッセージは次の 形式です:

struct cmsghdr {

u_int

cmsg_len;

/* データバイトカウント、hdr を含む */

int

cmsg_level;

/* メッセージを生成したプロトコル */

int

cmsg_type;

/* プロトコルに固有のタイプ */

/*

u_char

cmsg_data[]; が後に続く */

};

たとえば、これを使用して XNS/SPP においてデータストリームの変化を知ること ができます。また、ISO において accept() システムコールの直後に、データ バッファを伴わずに recvmsg() を要求して、ユーザ接続要求データを得ることが できるでしょう。

オープンファイル記述子はこれで AF_UNIX ドメインソケット用の補助データとし て引き渡され、その際、 cmsg_level が SOL_SOCKET に設定され、 cmsg_type が SCM_RIGHTS に設定されます。

SCM_CREDS の cmsg_type を使用して、プロセスの認証情報を AF_UNIX ドメイン ソケット用の補助データとして渡すこともできます。このケースでは、 cmsg_data は、構造体 cmsgcred である必要があります。これは次のように <sys/socket.h> 内で定義されています:

struct cmsgcred {

pid_t

cmcred_pid;

/* 送信プロセスの PID */

uid_t

cmcred_uid;

/* 送信プロセスの実 UID */

uid_t

cmcred_euid;

/* 送信プロセスの実効 UID */

gid_t

cmcred_gid;

/* 送信プロセスの実 GID */

short

cmcred_ngroups;

/* グループの数 */

gid_t

cmcred_groups[CMGROUP_MAX];

/* グループ */

};

カーネルは送信プロセスの認証情報を記入し、それを受信側へ配信します。

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 はソケットを参照していません。

[EMSGSIZE]
recvmsg
() システムコールは、接続時にデータをやりとりす る権利 (ファイル記述子) を受信するために使用されまし た。しかしながら、受信プログラムには受け付けるための空 きファイル記述子スロットがありませんでした。この場合、 記述子がクローズされ、 recvmsg() への別の呼び出しに よって、どんなペンディング (未解決) のデータも返すこと ができます。

[EAGAIN]
ソケットが非ブロッキングとマークされているとき、受信操 作でブロックしました。あるいは、受信タイムアウトが設定 されていて、データが受信される前にタイムアウトになりま した。

[EINTR]
データが受信可能になる前に、受信がシグナルによって割込 まれました。

[EFAULT]
受信バッファポインタが、プロセスに割り当てられたアドレ ス空間の範囲外を指しています。

関連項目

fcntl(2), getsockopt(2), read(2), select(2), socket(2)

歴史

recv() 関数は 4.2BSD で登場しました。

FreeBSD 10.0 February 21, 1994 FreeBSD 10.0

スポンサーリンク