accept
更新日2007年01月09日
参照 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/accept_2.asp

機能
その accept 関数はソケットへの接続要求試みを可能にします。

書式
SOCKET accept(
  SOCKET s,
  struct sockaddr* addr,
  int* addrlen
);
引数
s [入] listen 関数によって聞いているステートにて置かれたソケット識別子。 accept により戻されたソケットによって、接続は実際に作られました。
addr [出] 通信層に知られているとして、接続エントリーのアドレス受け入れ用バッファへのオプションのポインター。 sockaddr 構造体よりのソケットが作成された時に確立されたアドレスファミリィにより addr パラメタの正確な形式は決定されます。
addrlen [入、出] addr の長さを含む整数へのオプションのポインター。
戻り値
エラーが発生しないならば、 新しいソケットのための記述子である SOCKET 型の値を accept は戻します。 この戻された値は、実際の接続がなされるソケットのためのハンドルです。

さもなければ、INVALID_SOCKET 値は戻されます、 そして、特定のエラーコードは、WSAGetLastErrorを呼び出しにより検索する事が出来ます。

まず最初に addrlen によって言及される整数は、addr によって指されるスペースの量を含みます。 リターン時に、それは戻されるアドレスのバイトの実際の長さを含みます。

エラーコード 意味
WSANOTINITIALISED
この関数を使用する以前に WSAStartup 呼び出しを成功させておく必要があります。
WSAECONNRESET
入って来る接続は示されたが、呼び出しを受け入れる前に、遠隔の同志によってその後終了されました。
WSAEFAULT
addrlen パラメータは小さ過ぎます、あるいは、addr はユーザーアドレス空間の有効な一部ではありません。
WSAEINTR
Windows Sockets 1.1が指令するブロッキングは、WSACancelBlockingCall を通してキャンセルされました。
WSAEINVAL
リスン関数は、受け入れるために、より前に訴えられませんでした。
WSAEINPROGRESS
Windows Sockets 1.1が指令するブロッキングは進行中です、あるいは、サービスプロバイダはコールバック機能をまだ処理しています。
WSAEMFILE
待ち行列はエントリー受け入れと同時に空ではありません、そして利用可能な記述子がありません。
WSAENETDOWN
ネットワークサブシステムは失敗しました。
WSAENOBUFS
バッファスペースが利用できません。
WSAENOTSOCK
記述子がソケットではありません。
WSAEOPNOTSUPP
リファレンスをつけられたソケットは、コネクションオリエンティドサービスをサポートするタイプではありません。
WSAEWOULDBLOCK
ソケットは ブロッキングされない様にマークされています、そして、接続は受け入れられるために存在しません。

注釈
ソケット s 上でのペンディング接続の待ち行列上にて最初の接続を引き出します。 それは、それから新しいソケットへのハンドルを作成して戻します。 新しく作成されたソケットは、実際の接続を処理するソケットです; それはソケット s としてのいくつかのプロパティを持ち、含まれる非同期イベントは WSAAsyncSelect または WSAEventSelect 関数にて登録されます。

もし、ペンディング接続が待ち行列上にて存在せず、 そして、ソケットがブロッキングとしてマークされているならば、接続が存在します、 その間、accept 関数は呼び出し者をブロック出来ます。 もしソケットがブロッキングではないとしてマークされ、 そして、ペンディングしない接続が待ち行列上にて存在するならば、 accept は以下に記述されるとしてエラーを戻します。 accept が戻す新しいソケットハンドルの完成な成功の後、 受け入れられたソケットはさらなる接続を受け入れするのに使用出来ません。 オリジナルソケットは開いているままに、新しい接続要求のためにリスンします。

通信層へ知られているように、 パラメータ addr は、接続エントリィのアドレスにて満たされている結果パラメータです、 addr パラメータの正確なフォーマットは通信が起こっているアドレスファミリィにより決定されます。 addrlen は値結果パラメータです; それはまず最初に addr によって指される空間量を含まなければなりません; 復帰時にそれは戻されるアドレスの実際の長さ(バイトでの)を含むでしょう。

accept 関数は SOCK_STREAM である接続志向ソケットタイプと共に使用されます。 もし addr and/or addrlen が NULLと等しいならば、 受け入れられたソケットの遠隔アドレスについての情報は戻されません。

Example Code
以下に accept 関数の使用例を示します。 [winsock2accept_example1.c]
/*
 * file:winsock2accept_example1.c
 * The accept function permits an incoming connection attempt on a socket.
 * 参照 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/accept_2.asp
 */
#include <stdio.h>
#include <winsock2.h>

int main()
{
    /*
     * 変数の宣言。
     */
    WSADATA wsaData;
    int iResult = 0;
    SOCKET ListenSocket;
    struct sockaddr_in service;
    SOCKET AcceptSocket;

    /*
     * Winsockの初期化。
     */
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != NO_ERROR)
    {
        printf("Error at WSAStartup()\n");
    }

    /*
     * Create a SOCKET for listening for
     * incoming connection requests.
     * 接続要求受入用のリスニング用のソケットを作成。
     */
    ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ListenSocket == INVALID_SOCKET)
    {
        printf("Error at socket(): %ld\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }
    
    /*
     * The sockaddr_in structure specifies the address family,
     * IP address, and port for the socket that is being bound.
     * そのsockaddr_in構造体はそのアドレスファミリィを指定する、
     * IPアドレス、そして、結びつけられているソケットのためのポート。
     */
    service.sin_family = AF_INET;
    service.sin_addr.s_addr = inet_addr("127.0.0.1");
    service.sin_port = htons(27015);
    
    if (bind(ListenSocket,
            (SOCKADDR *)&service,
            sizeof(service)) == SOCKET_ERROR)
    {
        printf("bind() failed.\n");
        closesocket(ListenSocket);
        return 1;
    }
    
    /*
     * Listen for incoming connection requests.
     * on the created socket
     * その構築されたソケットでの接続要求受入用のリッスン.
     */
    if (listen(ListenSocket, 1) == SOCKET_ERROR)
    {
        printf("Error listening on socket.\n");
    }
    
    /*
     * Create a SOCKET for accepting incoming requests.
     * 受入要求許可用のソケットを構築。
     */
    printf("Waiting for client to connect...\n");

    /*
     * Accept the connection.
     * その接続を許可。
     */
    while (1)
    {
        AcceptSocket = SOCKET_ERROR;
        while (AcceptSocket == SOCKET_ERROR)
        {
            AcceptSocket = accept(ListenSocket, NULL, NULL);
        }
        printf("Client connected.\n");
        ListenSocket = AcceptSocket;
        break;
    }
    
    WSACleanup();
    
    return 0;
}

ATM用のノーツ

以下は、接続セットアップ関連する重要な発行です、 そして、Windows Sockets 2で非同期転送モード(ATM)を使用するとき、考慮されなければなりません:

  • acceptWSAAccept 関数は、 遠隔アドレスとアドレスの長さパラメータを必ずしもセットすると言うわけではありません。 それ故に、ATM を使用するとき、 呼び出し者は WSAAccept 関数を使用して、そして、 QOS 構造体の ProviderSpecific メンバに ATM_CALLING_PARTY_NUMBER_IE をセットするべきです。 WSAAccept に従って使用されるコールバック関数の lpSQOS パラメータの中にそれ自身が含まれます。
  • accept 関数を使用する時、 接続確立が送信者と受信者の間の全体の相違を全探索される前に、 関数が戻すかもしれない、と悟りましょう。 これは CONNECT ACK メッセージを受け取るとすぐに、accept 関数は戻ってくるとという理由です。 ATM では、CONNECT メッセージが処理されるとすぐに、経路の次のスイッチは CONNECT ACK メッセージを戻します (接続が結局確立されるエンドノードによって送られる CONNECT ACK よりむしろ)。 そういうものとして、CONNECT ACK メッセージの受け取るに従って、すぐにデータを送るなら、 アプリケーションはそれがわかるべきです、 データの損失は可能です、 以来、接続は送付者と受信機の間のいっぱいに確立されていないかもしれません。

要求環境
ヘッダ Declared in winsock2.h
ライブラリ Requires libws2_32.a

参照
Winsock Reference
Winsock Functions
bind
connect
listen
select
sockaddr
socket
WSAAsyncSelect
WSAAccept