Windows ソケット:ブロッキング
この記事と 2 つの関連記事では、Windows ソケット プログラミングにおけるいくつかの問題について説明します。 この記事では、ブロッキングについて説明します。 その他の問題については、「Windows ソケット: バイトの順序付け」と「Windows ソケット: 文字列の変換」という記事で説明されています。
CAsyncSocket クラスを使用するか、このクラスから派生させる場合は、これらの問題を自分で管理する必要があります。 CSocket クラスを使用するか、このクラスから派生させる場合は、これらの問題が MFC によって管理されます。
ブロック
ソケットは、"ブロッキング モード" または "非ブロッキング モード" になることができます。ブロッキング (または同期) モードのソケットの関数は、アクションを完了できるまで制御を返しません。 これがブロッキングと呼ばれるのは、関数を呼び出されたソケットが、呼び出しが制御を返すまで何も実行できない (ブロックされている) ためです。 たとえば、Receive
メンバー関数の呼び出しは、完了までに任意の長時間がかかる場合があります。この呼び出しは、送信側のアプリケーションによる送信を待機するためです (これは、CSocket
を使用しているか、CAsyncSocket
をブロッキングで使用している場合)。 CAsyncSocket
オブジェクトが非ブロッキング モード (非同期の動作) である場合、呼び出しはすぐに制御を返します。GetLastError メンバー関数を使用して取得できる現在のエラー コードは WSAEWOULDBLOCK であり、モードのためにすぐに制御が返されるのでなかったとしたら、呼び出しがブロックしただろうということを示します (CSocket
WSAEWOULDBLOCK を返しません。このクラスはブロックを管理します)。)
ソケットの動作は、32 ビットおよび 64 ビットのオペレーティング システム (Windows 95、Windows 98 など) と 16 ビットのオペレーティング システム (Windows 3.1 など) では異なります。 16 ビットのオペレーティング システムとは異なり、32 ビットおよび 64 ビットのオペレーティング システムはプリエンプティブなマルチタスクを使用し、マルチスレッドを提供します。 32 ビットおよび 64 ビットのオペレーティング システムでは、複数のソケットを個別のワーカー スレッドに配置できます。 スレッド内のソケットは、アプリケーション内の他のアクティビティに影響を与えずにブロックできます。また、ブロッキングにコンピューティング時間を費やすこともありません。 マルチスレッド プログラミングの詳細については、マルチスレッドに関する記事を参照してください。
Note
マルチスレッド アプリケーションでは、CSocket
のブロッキングの性質を利用して、ユーザー インターフェイスの応答性に影響を与えることなく、プログラムの設計を簡略化できます。 ユーザーによる操作をメイン スレッドで処理し、CSocket
のプロセスを代替スレッドで処理することで、これらの論理演算を分離できます。 マルチスレッドでないアプリケーションでは、これらの 2 つのアクティビティを組み合わせて 1 つのスレッドとして処理する必要があります。つまり、通常は、CAsyncSocket
を使用して通信要求をオンデマンドで処理できるようにするか、CSocket::OnMessagePending
をオーバーライドして時間のかかる同期アクティビティ中にユーザー操作を処理することになります。
この説明の残りの部分は、16 ビットのオペレーティング システムを対象とするプログラマ向けです。
通常、CAsyncSocket
を使用している場合は、ブロッキング操作の使用を避け、代わりに非同期的に操作する必要があります。 非同期操作では、たとえば Receive
の呼び出し後に WSAEWOULDBLOCK エラー コード受け取った時点から、もう一度読み取ることができることを通知するために OnReceive
メンバー関数が呼び出されるまで待機します。 非同期呼び出しは、ソケットの適切なコールバック通知関数 (OnReceive など) をコールバックすることによって行われます。
Windows では、ブロッキング呼び出しは不適切な方法と見なされます。 既定では、CAsyncSocket では非同期呼び出しがサポートされており、コールバック通知を使用して自分でブロッキングを管理する必要があります。 一方、クラス CSocket は同期的です。 Windows メッセージをポンプし、プログラマの代わりにブロッキングを管理します。
ブロッキングの詳細については、Windows Sockets の仕様を参照してください。 "On" 関数の詳細については、「Windows ソケット: ソケット通知」および「Windows ソケット: ソケット クラスからの派生」を参照してください。
詳細については、以下を参照してください: