accept_and_recv() - 接続の受け入れと最初のメッセージの受信

標準

標準/拡張機能 C/C++ 依存項目
z/OS®UNIX 両方  

形式

X/Open:
#define _OPEN_SYS_SOCK_EXT2
#include <sys/socket.h>

int accept_and_recv(int socket, int *accept_socket,
                    struct sockaddr *remote_address,
                    socklen_t *remote_address_len,
                    struct sockaddr *local_address,
                    socklen_t *local_address_len,
                    void *buffer, size_t buffer_len);

機能説明

accept_and_recv() 関数は、保留状態の接続のキューにある最初の接続 を抽出します。この関数は、指定したソケットを再使用する か (*accept_socket が -1 でない場合)、または listen ソケットと同じ ソケット・タイプ、プロトコル、およびアドレス・ファミリーで新しいソケット を作成します (*accept_socket が -1 の場合)。この関数は、その後、ピアで送信されたデータの最初のブロックを戻し、接続に関連したローカルおよびリモート・ソケット・アドレスを戻します。

この関数は、次の引数をとります。
パラメーター
説明
socket
socket() で作成されて bind() でアドレスにバインドされ、正常な呼び出し を listen() に発行したソケットを指定します。
accept_socket
着信接続を受け入れるソケットを指定する int へのポインター。そのソケットは、バインド済みであったり接続されていてはなりません。このパラメーターを使用すると、アプリケーションは、受け入れ側ソケットを 再使用できます。システムは、この引数でアプリケーションが指定したソケット とは異なるソケットを再使用することもできます。この場合、システムは、実際に再使用されるソケット に *accept_socket を設定します。

*accept_socket に対する -1 の値は、受け入れ側ソケットが、システムによって割り当てられる必要があり、このパラメーターのアプリケーションに戻される必要があることを意味します。accept_and_recv() の最初の呼び出しで -1 を使用することをお勧めします。詳細は、使用上の注意を参照してください。

remote_address
NULL ポインター、または接続中ソケットのアドレスが 戻される sockaddr 構造体へのポインター。
remote_address_len
socklen_t を指します。入力において、これは提供される sockaddr 構造体の長さを指定します。出力時には、保管されたアドレスの長さがここに含まれます。
local_address
NULL ポインター、またはローカル・ソケットの アドレスが戻される sockaddr 構造体へのポインター。
local_address_len
socklen_t を指します。入力において、これは提供される sockaddr 構造体の長さを指定します。出力時には、保管されたアドレスの長さがここに含まれます。
buffer
NULL ポインター、またはメッセージが保管 されるバッファーへのポインター。これが NULL ポインターの場合、受信が実行されることはなく、着信接続が受信されると accept_and_recv() は完了します。
buffer_len
buffer 引数が指すバッファーの長さをバイト 単位で指定します。

*accept_socket が -1 でない場合、着信接続 は、*accept_socket によって指定したソケットで受け入れられます。システムは、異なるソケットを再使用することもできます。この場合、システムは、実際に再使用されるソケットを反映する よう *accept_socket を変更します。

remote_address が NULL ポインターでない場合 は、受け入れられる接続に対するピアのアドレスは、remote_address が 指す sockaddr 構造体に保管され、このアドレスの長さ は、remote_address_len が指すオブジェクトに保管されます。提供されたソケット・アドレス構造体の長さよりもアドレスの実際の長さ のほうが長い場合、アドレスは切り捨てられて保管されます。

local_address が NULL ポインターでない場合 は、この接続に関連したローカル・ソケットのアドレス は、local_address が指す sockaddr 構造体に保管され、このアドレスの長さは、local_address_len が指すオブジェクトに 保管されます。提供されたソケット・アドレス構造体の長さよりもアドレスの実際の長さ のほうが長い場合、アドレスは切り捨てられて保管されます。

この関数の場合、非ブロック化モードはサポートされません。O_NONBLOCK をソケット・ファイル記述子に設定すると、この関数は -1 で戻り、errno が EOPNOTSUPP に設定されます。

listen キューに接続要求がないと、着信接続が受信されるまで、accept_and_recv() は、戻らなくなります。

buffer が NULL でない場合、接続のデータの最初のブロックが受信されるまで、accept_and_recv は戻りません。buffer が NULL の場合、接続が確立した後に、accept_and_recv() は 0 を戻します。

注: accept_and_recv() 関数は、拡張 ASCII の拡張機能のレベルに依存します。詳細は、拡張 ASCII サポートを参照してください。

使用上の注意

  1. accept_and_recv() の最初の呼び出しでは、アプリケーションにおいて accept_socket が指すソケットを -1 に設定することをお勧めします。これにより、受信ソケットが割り当てられます。アプリケーションは、この場合、accept_and_recv() の次回の呼び出しに、割り当てられた値を 渡します (accept_socket = socket_ptr と設定)。

    accept_and_recv() 関数によってもたらされるパフォーマンス向上を十分 に利用するには、親がループ内で受け入れて子プロセス・スレッドをスピンオフ するモデルとは異なるプロセス/スレッド・モデルが必要です。親/プロセス・スレッドは除去されます。複数のワーカー・プロセス/スレッドが作成され、各ワーカー・ プロセス/スレッドは、accept_and_recv() 関数をループ内で実行します。accept_and_recv() のパフォーマンス上の利点として、バッファー・コピー が少なくなること、ソケットがリサイクルされること、スケジューリングが最適に なることなどが挙げられます。

戻り値

正常に実行された場合、accept_and_recv() は、buffer 引数が指すバッファーに保管されたバイト数 (0 以上) を戻します。0 は、バッファーが NULL、またはクライアントがデータを送信せずにソケットを閉じたときに戻されます。

部分的な正常終了になると、*accept_socket が割り当てられ、戻り値は -1 に、errno が以下のいずれかの値に設定されます。

エラー・コード
説明
EINTRNODATA
accept_and_recv() 関数は、有効な接続が確立してからデータ の最初のブロックが着信するまでの間にキャッチされたシグナルによって、割り込まれました。
EWOULDBLOCK
新規接続が確立されましたが、SO_RCVTIMEO タイムアウト値に 達したためデータを使用できませんでした。

正常に実行されなかった場合、accept_and_recv() は *accepted_socket を -1 に設定し、-1 を戻し、errno を以下のいずれかの値に設定します。

エラー・コード
説明
EBADF
次の 2 つのエラーのどちらかが発生します。
  1. socket は有効な記述子ではありません。
  2. accept_socket が有効な記述子を指しません。
ECONNABORTED
接続が打ち切られました。
ECONNRESET
接続はピアによって強制的にクローズされました。
EFAULT
accept_socketremote_addressremote_address_lenlocal_addresslocal_address_len、または buffer が指すデータ・ バッファーは無効です。
EINTR
accept_and_recv() 関数は、有効な接続が確立する前に キャッチされたシグナルによって割り込まれました。
EINVAL
socket は、接続の受け入れ中 ではありません。
EIO
入出力エラーが発生しました。
EISCONN
accept_socket は、既にバインドされているかまたは 接続されています。
EMFILE
OPEN_MAX 記述子は、呼び出し プロセスで既にオープンしています。
ENOBUFS
バッファー・スペースを使用できません。
ENOMEM
メモリーが不十分なので、操作を完了できませんでした。
ENOREUSE
ソケットの再使用はサポートされません。
ENOSR
STREAMS リソースが不十分なため、操作を完了できませんでした。
ENOTSOCK
socket 引数がソケットを参照しない、または accept_socket がソケットを指していません。
EOPNOTSUPP
次のいずれかのエラーが発生しました。
  1. ソケットのタイプが 接続の受け入れをサポートしません。
  2. O_NONBLOCK がソケットに設定されているが、この関数の 場合、非ブロック化がサポートされません。

関連情報