重複した I/O オブジェクトとイベント オブジェクト

Windows Sockets 2 では重複する I/O がサポートされており、すべてのトランスポート プロバイダーがこの機能をサポートしています。 重複した I/O は、Windows で確立されたモデルに従い、ソケット関数で作成されたソケット、または dwFlags パラメーターにWSA_FLAG_OVERLAPPED フラグが設定された WSASocket 関数で作成されたソケットで実行できます。

Note

重複する属性を使用してソケットを作成しても、ソケットが現在ブロッキング モードか非ブロッキング モードかに影響しません。 重複した属性を使用して作成されたソケットを使用して、重複した I/O を実行できます。これにより、ソケットのブロック モードは変更されません。 重複する I/O 操作はブロックしないため、ソケットのブロック モードはこれらの操作には関係ありません。

 

受信の場合、アプリケーションは WSARecv 関数または WSARecvFrom 関数を使用して、データを受信するバッファーを提供します。 ネットワークによってデータが受信された時刻より前に 1 つ以上のバッファーがポストされた場合、そのデータは到着直後にユーザーのバッファーに配置される可能性があります。 したがって、recv または recvfrom 関数が呼び出されたときに発生するコピー操作を回避できます。 受信バッファーのポスト時にデータが既に存在する場合は、ユーザーのバッファーにすぐにコピーされます。

アプリケーションによって受信バッファーがポストされていないときにデータが到着した場合、ネットワークは使い慣れた同期スタイルの操作に頼ります。 つまり、受信データは、アプリケーションが受信呼び出しを発行し、それによってデータをコピーできるバッファーを提供するまで、内部的にバッファーされます。 例外は、アプリケーションが setsockopt を使用して受信バッファーのサイズを 0 に設定する場合です。 この例では、信頼性の高いプロトコルでは、アプリケーション バッファーがポストされ、信頼性の低いプロトコルのデータが失われた場合にのみ、データを受信できます。

送信側では、アプリケーションは WSASend または WSASendTo を使用して塗りつぶされたバッファーへのポインターを提供し、ネットワークがバッファーの内容を消費するまでバッファーを邪魔しないことに同意します。

重複する送受信呼び出しはすぐに返されます。 戻り値 0 は、I/O 操作が直ちに完了したこと、および対応する完了表示が既に発生したことを示します。 つまり、関連付けられたイベント オブジェクトが通知されたか、完了ルーチンがキューに登録され、呼び出し元のスレッドがアラート可能な待機状態になったときに実行されます。

SOCKET_ERRORの戻り値と エラー コードWSA_IO_PENDING は、重複した操作が正常に開始され、送信バッファーが使用されたとき、または受信操作が完了したときに後続の指示が提供されることを示します。 ただし、バイト ストリーム スタイルのソケットの場合、バッファーがいっぱいかどうかに関係なく、受信データが使い果たされるたびに完了の兆候が発生します。 その他のエラー コードは、重複した操作が正常に開始されなかったことを示し、完了の兆候が今後発生しないことを示します。

送受信の両方の操作を重複させることができます。 受信関数は、受信データに備えて受信バッファーをポストするために複数回呼び出すことができます。また、送信関数を複数回呼び出して、送信する複数のバッファーをキューに入れることもできます。 アプリケーションは、指定された順序で送信される一連の重複する送信バッファーに依存できますが、対応する完了表示が異なる順序で発生する可能性があります。 同様に、受信側では、バッファーは指定された順序で入力できますが、完了の兆候は別の順序で発生する可能性があります。

多くの場合、 AcceptExConnectExWSASendWSARecvTransmitFile などの関数を使用して Winsock が重複した操作はキャンセル可能です。 ただし、未処理の操作を取り消したソケットを引き続き使用する場合、動作は未定義です。 closesocket 関数は、重複する操作を取り消した後に呼び出す必要があります。 したがって、最良の結果を得るには、I/O を直接取り消すのではなく、 closesocket 関数を呼び出してソケットを閉じ、最終的に保留中のすべての操作を中止する必要があります。

重複した I/O の遅延完了機能は、ioctlsocket の拡張バージョンである WSAIoctl でも使用できます。