accept() - ソケットに関する新規接続の受け入れ
標準
| 標準/拡張機能 | C/C++ | 依存項目 |
|---|---|---|
XPG4.2 |
両方 |
形式
#define _XOPEN_SOURCE_EXTENDED 1
#include <sys/socket.h>
int accept(int socket, struct sockaddr *__restrict__ address,
socklen_t *__restrict__address_len);
#define _OE_SOCKETS
#include <sys/types.h>
#include <sys/socket.h>
int accept(int socket, struct sockaddr *address, int *address_len);
機能説明
- パラメーター
- 説明
- socket
- ソケット記述子。
- address
- accept() が戻る前に、これによって埋められた接続クライアントのソケット・アドレス。address の形式は、クライアントが常駐している ドメインで決定されます。呼び出し元がクライアント・アドレスに関係していない場合、このパラメーターを NULL にすることはできません。
- address_len
- address が示すストレージのサイズ (バイト) を含む 整数を最初に指す必要があります。戻りの際に、その整数には、接続ソケットのアドレス を表すために必要なサイズが入ります。 この値が、入力のときに提供されたサイズより大きい場合、sockaddr に入っている情報は、入力のときに提供された長さまで切り捨てられます。address が NULL であると、address_len は無視されます。
socket パラメーターは、socket() 呼び出しで作成されるストリーム・ソケット記述子です。これは、通常は bind() 呼び出しを使ってアドレスにバインドされます。listen() 呼び出しは、保留接続要求を保持するために接続を受け入れてキューを割り振るものとして、ソケットにマークを付けます。listen() 呼び出しは、キューのサイズに関して上部境界を設定します。
address パラメーターは、接続リクエスターの アドレスが配置されるバッファーを指すポインターです。address パラメーターはオプション で、NULL ポインターになるように設定することができます。NULL に設定すると、リクエスターのアドレスは バッファーにコピーされません。address の正確な形式は、通信要求の発信元の アドレッシング・ドメインに依存します。例えば、接続要求の発信元が AF_INET ドメインの場合、address は、sockaddr_in 構造体を指し、接続要求の発信元が AF_INET6 ドメインの場合は、address は、sockaddr_in6 構造体を指します。 sockaddr_in および sockaddr_in6 構造体は、 netinet/in.h の中に定義されます。 address_len パラメーターは、address が NULL でない時にのみ使用されます。 accept() を呼び出す前に、address で示されたバッファー・サイズ (バイト) に、address_len で示された整数を設定しなければなりません。正常終了の戻りでは、address_len で示された整数に、バッファーにコピーされた実際のバイト数が入っています。バッファーが、アドレスを保持するのに十分な大きさでない 場合、リクエスターのアドレスの最高 address_len バイトまでがコピーされます。アドレスの実際の長さが、提供される sockaddr を 超える場合、保管されるアドレスは切り捨てられます。保管構造体の sa_len メンバーには、切り捨てられていないアドレスの長さが含まれます。
- この呼び出しは、SOCK_STREAM ソケットだけで使用されます。accept() を呼び出さずにリクエスターを覆う方法はありません。アプリケーションは、接続の受け入れ元となるリクエスターをシステムに 伝えることができません。しかし、呼び出し元はリクエスターの一致を発見した後で、接続を即時にクローズするように選ぶことができます。
- accept() 関数は、拡張 ASCII の拡張機能のレベルに依存します。詳細は、拡張 ASCII サポートを参照してください。
select() 呼び出しを使用して、着信接続要求がないかどうかソケットを確認できます。
C++ の特殊な動作: この関数を C++ で使用するには、_XOPEN_SOURCE_EXTENDED 1 フィーチャー・テスト・マクロを使用する必要があります。
戻り値
正常に実行された場合、accept() は、負でないソケット記述子を戻します。
- エラー・コード
- 説明
- EAGAIN
- ID を変更する呼び出しの受け入れ中に新規 ID の UID が 既に MAXPROCUID であれば、その呼び出しの受け入れは失敗します。
- EBADF
- socket パラメーターが、ソケット記述子の 許容範囲内にありません。
- EFAULT
- address と address_len を使用 した結果、情報を書き込むことができない呼び出し元の アドレス・スペース部分にアドレスをコピーしようとしました。
- EINTR
- 任意の接続が使用可能になる前に、シグナルが accept() 呼び出しに割り込みました。
- EINVAL
- listen() が、ソケット記述子の socket 用に呼び出されませんでした。
- EIO
- ネットワークまたはトランスポートで障害が発生しました。
- EMFILE
- このプロセスに許容されたファイル記述子の最大数を 超えて、オープンしようとしました。
- EMVSERR
- ID の変更を生じる 2 つの連続した呼び出しの受け入れは許可されません。ID を変更する受け入れがさらに許可されるためには、その前に、元 の ID を復元する (ID の変更を生じたソケットを close() する) 必要があります。
- ENFILE
- システムのファイル記述子の最大数が 既にオープンしています。
- ENOBUFS
- 新しいソケットを作成するのに 十分なバッファー・スペースが使用できません。
- ENOTSOCK
- socket パラメーターが有効な ソケット記述子を参照しません。
- EOPNOTSUPP
- 指定されたソケットのソケット・タイプが 接続の受け入れをサポートしません。
- EWOULDBLOCK
- ソケット記述子の socket が非ブロック化モード であり、キューに接続がありません。
例
int clientsocket;
int s;
struct sockaddr clientaddress;
int address_len;
int accept(int s, struct sockaddr *addr, int *address_len);
/* socket(), bind(), and listen()
have been called */
/* EXAMPLE 1: I want the address now */
address_len = sizeof(clientaddress);
clientsocket = accept(s, &clientaddress, &address_len);
/* EXAMPLE 2: I can get the address later using getpeername() */
clientsocket = accept(s, (struct sockaddr *) 0,
(int *) 0);