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 が指す領域の量が含まれます。戻り値には、返されるアドレスの実際の長さ (バイト単位) が含まれます。
エラー コード | 意味 |
---|---|
この関数を使用する前に、 WSAStartup 呼び出しが正常に行われる必要があります。 | |
着信接続が示されましたが、その後、呼び出しを受け入れる前にリモート ピアによって終了されました。 | |
addrlen パラメーターが小さすぎるか、addr がユーザー アドレス空間の有効な部分ではありません。 | |
WSACancelBlockingCall を使用して、Windows ソケット 1.1 の呼び出しをブロックしているが取り消されました。 | |
リッスン関数は、受け入れる前に呼び出されませんでした。 | |
ブロックしている Windows Sockets 1.1 呼び出しが進行中であるか、サービス プロバイダーがコールバック関数を処理しています。 | |
キューは、 受け入れる 際に空でなく、使用できる記述子がありません。 | |
ネットワーク サブシステムが失敗しました。 | |
バッファーに空き領域がありません。 | |
記述子はソケットではありません。 | |
参照されるソケットは、接続指向サービスをサポートする型ではありません。 | |
ソケットは非ブロッキングとしてマークされ、受け入れられる接続はありません。 |
accept 関数は、ソケットの保留中の接続のキューで最初の接続を抽出します。 次に、ハンドルを作成して新しいソケットに返します。 新しく作成されたソケットは、実際の接続を処理するソケットです。WSAAsyncSelect 関数または WSAEventSelect 関数に登録されている非同期イベントなど、ソケットと同じプロパティがあります。
キューに保留中の接続が存在せず、ソケットがブロッキングとしてマークされている場合、 accept 関数は接続が存在するまで呼び出し元をブロックできます。 ソケットが非ブロッキングとしてマークされ、保留中の接続がキューに存在しない場合は、次に示すように、 を受け入れると エラーが返されます。 accept が正常に完了すると、新しいソケット ハンドルが返された後、受け入れられたソケットを使用して、より多くの接続を受け入れることはできません。 元のソケットは開いたままで、新しい接続要求をリッスンします。
パラメーター addr は、通信レイヤーに知られているように、接続エンティティのアドレスで入力される結果パラメーターです。 addr パラメーターの正確な形式は、通信が行われているアドレス ファミリによって決まります。 addrlen は値の結果パラメーターです。最初は、addr が指す領域の量を含める必要があります。を返すと、返されるアドレスの実際の長さ (バイト単位) が含まれます。
accept 関数は、SOCK_STREAMなどの接続指向のソケット型で使用されます。 addr や addrlen が NULL と等しい場合、受け入れられたソケットのリモート アドレスに関する情報は返されません。
#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 ではじめにする」を参照してください。
接続のセットアップに関連する重要な問題を次に示します。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.1とWindows 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 |