LPFN_CONNECTEX コールバック関数 (mswsock.h)
ConnectEx 関数は、指定されたソケットへの接続を確立し、必要に応じて接続が確立されるとデータを送信します。 ConnectEx 関数は、接続指向ソケットでのみサポートされます。
構文
LPFN_CONNECTEX LpfnConnectex;
BOOL LpfnConnectex(
[in] SOCKET s,
[in] const sockaddr *name,
[in] int namelen,
[in, optional] PVOID lpSendBuffer,
[in] DWORD dwSendDataLength,
[out] LPDWORD lpdwBytesSent,
[in] LPOVERLAPPED lpOverlapped
)
{...}
パラメーター
[in] s
接続されていない、以前にバインドされたソケットを識別する記述子。 詳細については、「解説」を参照してください。
[in] name
へのポインター
接続先のアドレスを指定する sockaddr 構造体。 IPv4 の場合、 sockaddr には、アドレス ファミリ、宛先 IPv4 アドレス、および宛先ポートの AF_INET が含まれます。 IPv6 の場合、 sockaddr 構造体にはアドレス ファミリの AF_INET6 、宛先 IPv6 アドレス、宛先ポートが含まれており、追加の IPv6 フローとスコープ ID 情報を含む場合があります。
[in] namelen
name パラメーターが指す sockaddr 構造体の長さ (バイト単位)。
[in, optional] lpSendBuffer
接続が確立された後に転送されるバッファーへのポインター。 このパラメーターは省略可能です。 ConnectEx が呼び出される前に TCP_FASTOPEN オプションが s で有効になっている場合は、接続の確立中にこのデータの一部が送信される可能性があります。
[in] dwSendDataLength
lpSendBuffer パラメーターが指すデータの長さ (バイト単位)。 lpSendBuffer パラメーターが NULL の場合、このパラメーターは無視されます。
[out] lpdwBytesSent
正常に戻った場合、このパラメーターは、接続が確立された後に送信されたバイト数を示す DWORD 値を指します。 送信されるバイトは、 lpSendBuffer パラメーターによって指されるバッファーから送信されます。 lpSendBuffer パラメーターが NULL の場合、このパラメーターは無視されます。
[in] lpOverlapped
要求の処理に使用される OVERLAPPED 構造体。 lpOverlapped パラメーターを指定する必要があり、NULL にすることはできません。
戻り値
成功すると、 ConnectEx 関数は TRUE を返します。 失敗した場合、関数は FALSE を返します。 WSAGetLastError 関数を使用して、拡張エラー情報を取得します。 WSAGetLastError 関数の呼び出しがERROR_IO_PENDINGを返した場合、操作は正常に開始され、進行中です。 このような状況では、重複した操作が完了しても呼び出しが失敗する可能性があります。
返されるエラー コードが WSAECONNREFUSED、 WSAENETUNREACH、または WSAETIMEDOUT の場合、アプリケーションは ConnectEx、 WSAConnect を呼び出すか、同じソケットでもう一度 接続 できます。
エラー コード | 説明 |
---|---|
ConnectEx を使用する前に、WSAStartup 関数の呼び出しが正常に行われる必要があります。 | |
ネットワーク サブシステムが失敗しました。 | |
ソケットのローカル アドレスは既に使用されており、SO_REUSEADDRでアドレスを再利用できるようにソケットがマークされていません。 このエラーは通常、バインド操作中に発生しますが、ローカル IP アドレスに指定されたワイルドカード アドレス (INADDR_ANYまたはin6addr_any) でバインド関数が呼び出された場合、ConnectEx 関数の呼び出しまでエラーが遅延する可能性があります。 特定の IP アドレスは、 ConnectEx 関数によって暗黙的にバインドされている必要があります。 | |
指定したソケットで、非ブロッキング 接続、 WSAConnect、または ConnectEx 関数の呼び出しが進行中です。 | |
リモート アドレスは、ADDR_ANY などの有効なアドレスではありません ( ConnectEx 関数は、接続指向ソケットでのみサポートされます)。 | |
指定されたファミリーのアドレスをこのソケットと共に使用することはできません。 | |
接続の試行が拒否されました。 | |
name、lpSendBuffer、または lpOverlapped パラメーターがユーザー アドレス空間の有効な部分ではないか、namelen が小さすぎます。 | |
パラメーター s は、バインドされていないソケットまたはリッスンしているソケットです。 | |
ソケットは既に接続されています。 | |
現在このホストからネットワークには到達できません。 | |
到達できないホストに対してソケット操作を実行しようとしました。 | |
使用できるバッファー領域はありません。ソケットを接続できません。 | |
記述子はソケットではありません。 | |
接続の試行が、接続を確立せずにタイムアウトしました。 |
注釈
ConnectEx 関数は、複数のソケット関数を 1 つの API/カーネル遷移に結合します。 ConnectEx 関数の呼び出しが正常に完了すると、次の操作が実行されます。
- 新しい接続が確立されます。
- 接続が確立された後、オプションのデータ ブロックが送信されます。
Windows Vista 以降を対象とするアプリケーションの場合は、クライアント アプリケーションの設計を大幅に簡略化する WSAConnectByList または WSAConnectByName 関数の使用を検討してください。
ConnectEx 関数は、接続指向ソケットでのみ使用できます。 s パラメーターで渡されるソケットは、SOCK_STREAM、SOCK_RDM、またはSOCK_SEQPACKETのソケット型で作成する必要があります。
lpSendBuffer パラメーターは、接続が確立された後に送信するデータのバッファーを指します。 dwSendDataLength パラメーターは、送信するデータの長さをバイト単位で指定します。 アプリケーションは、send 関数と WSASend 関数を使用するのと同じ方法で、ConnectEx を使用してデータの大きなバッファーを送信するように要求できます。 ただし、この操作ではバッファー全体が送信されるまで大量のシステム メモリ リソースを使用するため、 ConnectEx を使用して 1 回の呼び出しで巨大なバッファーを送信しないことを強くお勧めします。
ConnectEx 関数が成功した場合、接続が確立され、lpSendBuffer パラメーターが指すすべてのデータが、name パラメーターが指す sockaddr 構造体で指定されたアドレスに送信されました。
ConnectEx 関数では、重複した I/O が使用されます。 その結果、 ConnectEx 関数を使用すると、アプリケーションは比較的少数のスレッドで多数のクライアントにサービスを提供できます。 これに対し、重複した I/O を使用しない WSAConnect 関数では、通常、同時要求を受信したときに各接続要求を処理するために個別のスレッドが必要です。
多くの場合、接続指向ソケットは接続をすぐに完了できないため、操作が開始され、関数はERROR_IO_PENDINGまたはWSA_IO_PENDINGエラーで直ちに戻ります。 接続操作が完了し、成功または失敗が達成されると、 lpOverlapped に示されている完了通知メカニズムを使用して状態が報告されます。 すべての重複する関数呼び出しと同様に、完了通知メカニズムとしてイベントまたは完了ポートを使用できます。 GetQueuedCompletionStatus または GetOverlappedResult 関数または WSAGetOverlappedResult 関数の lpNumberOfBytesTransferred パラメーターは、要求で送信されたバイト数を示します。
ConnectEx 関数が正常に完了すると、ソケット ハンドル s を次の関数にのみ渡すことができます。
TF_DISCONNECTフラグとTF_REUSE_SOCKETフラグの両方を持つ以前に接続されたソケットで TransmitFile 関数が呼び出された場合、指定されたソケットは接続されていないがバインドされた状態に戻されます。 このような場合、ソケットのハンドルは、 の パラメーターで ConnectEx 関数に渡すことができますが、AcceptEx 関数呼び出しではソケットを再利用できません。 同様に、 TransmitFile 関数を使用して再利用された受け入れられたソケットは 、ConnectEx の呼び出しでは使用できません。 再利用されたソケットの場合、 ConnectEx は基になるトランスポートの動作の影響を受けることに注意してください。 たとえば、TCP ソケットは TCP TIME_WAIT状態の影響を受け、 ConnectEx 呼び出しが遅延する可能性があります。
ConnectEx 関数が TRUE を返すと、ソケット s は接続されているソケットの既定の状態になります。 ソケット s では、ソケットで SO_UPDATE_CONNECT_CONTEXTが設定されるまで、以前にプロパティまたはオプションを設定することはできません。 setsockopt 関数を使用して、SO_UPDATE_CONNECT_CONTEXT オプションを設定します。
例:
//Need to #include <mswsock.h> for SO_UPDATE_CONNECT_CONTEXT
int iResult = 0;
iResult = setsockopt( s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0 );
getsockopt 関数を SO_CONNECT_TIME ソケット オプションと共に使用して、ConnectEx の進行中に接続が確立されたかどうかをチェックできます。 接続が確立されている場合、getsockopt 関数に渡される optval パラメーターで返される値は、ソケットが接続された秒数です。 ソケットが接続されていない場合、返される optval パラメーターには0xFFFFFFFFが含まれます。 この方法で接続を確認することは、データを送信せずに一定期間接続が確立されているかどうかを判断するために必要です。このような場合は、そのような接続を終了することをお勧めします。
例:
//Need to #include <mswsock.h> for SO_CONNECT_TIME
int seconds;
int bytes = sizeof(seconds);
int iResult = 0;
iResult = getsockopt( s, SOL_SOCKET, SO_CONNECT_TIME,
(char *)&seconds, (PINT)&bytes );
if ( iResult != NO_ERROR ) {
printf( "getsockopt(SO_CONNECT_TIME) failed with error: %u\n",
WSAGetLastError() );
}
else {
if (seconds == 0xFFFFFFFF)
printf("Connection not established yet\n");
else
printf("Connection has been established %ld seconds\n",
seconds);
}
name パラメーターで指されている sockaddr 構造体の address パラメーターがすべて 0 の場合、ConnectEx はエラー WSAEADDRNOTAVAIL を返します。 アクティブな接続を再接続しようとすると、エラー コード WSAEISCONN で失敗します。
何らかの理由で接続されたソケットが閉じられると、ソケットを破棄し、新しいソケットを作成することをお勧めします。 その理由は、何らかの理由で接続されたソケットで問題が発生した場合、アプリケーションはソケットを破棄し、必要なソケットをもう一度作成して安定したポイントに戻る必要があると考えるのが最も安全です。
DisconnectEx 関数が TF_REUSE_SOCKET フラグを使用して呼び出された場合、指定されたソケットは接続されていないがバインドされた状態に戻されます。 このような場合、ソケットのハンドルは、その s パラメーターで ConnectEx 関数に渡すことができます。
TCP が閉じた接続を解放してそのリソースを再利用するまでに経過する必要がある時間間隔は、TIME_WAIT状態または 2MSL 状態と呼ばれます。 この間、新しい接続を確立するよりも、クライアントとサーバーに対するコストを大幅に削減して、接続を再度開くことができます。
TIME_WAIT動作は RFC 793 で指定されているため、TCP はネットワークの最大セグメント有効期間 (MSL) の 2 倍以上の間隔で閉じた接続を維持する必要があります。 接続が解放されると、ソケットペアとソケットに使用される内部リソースを使用して、別の接続をサポートできます。
Windows TCP は、接続の終了後にTIME_WAIT状態に戻ります。 TIME_WAIT状態の間は、ソケット ペアを再利用できません。 TIME_WAIT期間は、TIME_WAIT期間を秒単位で表す次の DWORD レジストリ設定を変更することで構成できます。
Hkey_local_machine\システム\CurrentControlSet\サービス\Tcpip\パラメーター\TcpTimedWaitDelay
既定では、MSL は 120 秒に定義されています。 TcpTimedWaitDelay レジストリ設定の既定値は 240 秒で、120 秒または 4 分の最大セグメントの有効期間の 2 倍を表します。 ただし、このエントリを使用して間隔をカスタマイズできます。
このエントリの値を小さくすると、TCP は閉じた接続をより高速に解放でき、新しい接続のためのリソースを増やすことができます。 ただし、値が小さすぎると、TCP は接続が完了する前に接続リソースを解放する可能性があり、サーバーは接続を再確立するために追加のリソースを使用する必要があります。
このレジストリ設定は、0 ~ 300 秒に設定できます。
Windows Phone 8: この関数は、Windows Phone 8 以降のWindows Phone ストア アプリでサポートされています。
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 |
ヘッダー | mswsock.h |