accept 関数 (winsock2.h)

accept 関数は、ソケットに対する着信接続の試行を許可します。

構文

SOCKET WSAAPI accept(
  [in]      SOCKET   s,
  [out]     sockaddr *addr,
  [in, out] int      *addrlen
);

パラメーター

[in] s

listen 関数を使用してリッスン状態になっているソケットを識別する記述子。 実際には、 accept によって返されるソケットを使用して接続が確立されます。

[out] addr

通信層に知られているように、接続エンティティのアドレスを受け取るバッファーへのオプションのポインター。 addr パラメーターの正確な形式は、sockaddr 構造体のソケットが作成されたときに確立されたアドレス ファミリによって決まります。

[in, out] addrlen

addr パラメーターによって指される構造体の長さを含む整数への省略可能なポインター。

戻り値

エラーが発生しない場合、 accept は、新しいソケットの記述子である SOCKET 型の値を返します。 この戻り値は、実際の接続が行われるソケットのハンドルです。

それ以外の場合は、 INVALID_SOCKET の値が返され、 WSAGetLastError を呼び出すことによって特定のエラー コードを取得できます。

addrlen によって参照される整数には、最初に addr が指す領域の量が含まれます。戻り値には、返されるアドレスの実際の長さ (バイト単位) が含まれます。

エラー コード 意味
WSANOTINITIALIZED
この関数を使用する前に、 WSAStartup 呼び出しが正常に行われる必要があります。
WSAECONNRESET
着信接続が示されましたが、その後、呼び出しを受け入れる前にリモート ピアによって終了されました。
WSAEFAULT
addrlen パラメーターが小さすぎるか、addr がユーザー アドレス空間の有効な部分ではありません。
WSAEINTR
WSACancelBlockingCall を使用して、Windows ソケット 1.1 の呼び出しをブロックしているが取り消されました。
WSAEINVAL
リッスン関数は、受け入れる前に呼び出されませんでした。
WSAEINPROGRESS
ブロックしている Windows Sockets 1.1 呼び出しが進行中であるか、サービス プロバイダーがコールバック関数を処理しています。
WSAEMFILE
キューは、 受け入れる 際に空でなく、使用できる記述子がありません。
WSAENETDOWN
ネットワーク サブシステムが失敗しました。
WSAENOBUFS
バッファーに空き領域がありません。
WSAENOTSOCK
記述子はソケットではありません。
WSAEOPNOTSUPP
参照されるソケットは、接続指向サービスをサポートする型ではありません。
WSAEWOULDBLOCK
ソケットは非ブロッキングとしてマークされ、受け入れられる接続はありません。

注釈

accept 関数は、ソケット保留中の接続のキューで最初の接続を抽出します。 次に、ハンドルを作成して新しいソケットに返します。 新しく作成されたソケットは、実際の接続を処理するソケットです。WSAAsyncSelect 関数または WSAEventSelect 関数に登録されている非同期イベントなど、ソケット同じプロパティがあります。

キューに保留中の接続が存在せず、ソケットがブロッキングとしてマークされている場合、 accept 関数は接続が存在するまで呼び出し元をブロックできます。 ソケットが非ブロッキングとしてマークされ、保留中の接続がキューに存在しない場合は、次に示すように、 を受け入れると エラーが返されます。 accept が正常に完了すると、新しいソケット ハンドルが返された後、受け入れられたソケットを使用して、より多くの接続を受け入れることはできません。 元のソケットは開いたままで、新しい接続要求をリッスンします。

パラメーター addr は、通信レイヤーに知られているように、接続エンティティのアドレスで入力される結果パラメーターです。 addr パラメーターの正確な形式は、通信が行われているアドレス ファミリによって決まります。 addrlen は値の結果パラメーターです。最初は、addr が指す領域の量を含める必要があります。を返すと、返されるアドレスの実際の長さ (バイト単位) が含まれます。

accept 関数は、SOCK_STREAMなどの接続指向のソケット型で使用されます。 addraddrlenNULL と等しい場合、受け入れられたソケットのリモート アドレスに関する情報は返されません。

メモaccept などのブロッキング Winsock 呼び出しを発行する場合、Winsock は、呼び出しを完了する前にネットワーク イベントを待機する必要がある場合があります。 Winsock は、この状況でアラート可能な待機を実行します。この待機は、同じスレッドでスケジュールされた非同期プロシージャ 呼び出し (APC) によって中断される可能性があります。 同じスレッドで進行中の Winsock 呼び出しを中断した APC 内で別のブロック Winsock 呼び出しを発行すると、未定義の動作が発生し、Winsock クライアントが試行してはなりません。
 

コード例

次の例では、 accept 関数の使用方法を示します。
#ifndef UNICODE
#define UNICODE
#endif

#include <winsock2.h>
#include <WS2tcpip.h>
#include <stdio.h>
#include <windows.h>

// Need to link with Ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

int wmain(void)
{

    //----------------------
    // Initialize Winsock.
    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        wprintf(L"WSAStartup failed with error: %ld\n", iResult);
        return 1;
    }
    //----------------------
    // Create a SOCKET for listening for
    // incoming connection requests.
    SOCKET ListenSocket;
    ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ListenSocket == INVALID_SOCKET) {
        wprintf(L"socket failed with error: %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 service;
    service.sin_family = AF_INET;
    service.sin_port = htons(27015);
    inet_pton(AF_INET, "127.0.0.1", &service.sin_addr);

    if (bind(ListenSocket,
             (SOCKADDR *) & service, sizeof (service)) == SOCKET_ERROR) {
        wprintf(L"bind failed with error: %ld\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
    //----------------------
    // Listen for incoming connection requests.
    // on the created socket
    if (listen(ListenSocket, 1) == SOCKET_ERROR) {
        wprintf(L"listen failed with error: %ld\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
    //----------------------
    // Create a SOCKET for accepting incoming requests.
    SOCKET AcceptSocket;
    wprintf(L"Waiting for client to connect...\n");

    //----------------------
    // Accept the connection.
    AcceptSocket = accept(ListenSocket, NULL, NULL);
    if (AcceptSocket == INVALID_SOCKET) {
        wprintf(L"accept failed with error: %ld\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    } else
        wprintf(L"Client connected.\n");

    // No longer need server socket
    closesocket(ListenSocket);

    WSACleanup();
    return 0;
}


accept 関数を使用する別の例については、「winsock ではじめにする」を参照してください。

ATM に関する注意事項

接続のセットアップに関連する重要な問題を次に示します。Windows ソケット 2 で非同期転送モード (ATM) を使用する場合は考慮する必要があります。

  • accept 関数と WSAAccept 関数は、必ずしもリモート アドレスとアドレス長のパラメーターを設定するとは限りません。 したがって、ATM を使用する場合、呼び出し元は WSAAccept 関数を使用し、QoS 構造体の ProviderSpecific メンバーにATM_CALLING_PARTY_NUMBER_IEを配置する必要があります。このメンバー自体は、WSAAccept に従って使用されるコールバック関数の lpSQOS パラメーターに含まれます。
  • accept 関数を使用する場合、接続の確立が送信側と受信側の間の距離全体を走査する前に、関数が を返す可能性があることに気付きます。 これは、 受け入れ 関数が CONNECT ACK メッセージを受信するとすぐにを返すからです。ATM では、CONNECT メッセージが処理されるとすぐに(接続が最終的に確立されるエンド ノードによって送信される CONNECT ACK ではなく)、パス内の次のスイッチによって CONNECT ACK メッセージが返されます。 そのため、アプリケーションでは、CONNECT ACK メッセージの受信直後にデータが送信されると、送信側と受信側の間で接続が確立されていない可能性があるため、データ損失が発生する可能性があることに気付く必要があります。

Windows 8.1Windows Server 2012 R2: この関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows ストア アプリでサポートされています。

要件

要件
サポートされている最小のクライアント Windows 8.1、Windows Vista [デスクトップ アプリ |UWP アプリ]
サポートされている最小のサーバー Windows Server 2003 [デスクトップ アプリのみ | UWP アプリ]
対象プラットフォーム Windows
ヘッダー winsock2.h
Library Ws2_32.lib
[DLL] Ws2_32.dll

こちらもご覧ください

WSAAccept

WSAAsyncSelect

Winsock 関数

Winsock リファレンス

bind

connect

listen

select

Sockaddr

socket