名前付きパイプ操作

パイプ サーバーが初めて CreateNamedPipe 関数を呼び出す場合は、 nMaxInstances パラメーターを使用して、同時に存在できるパイプのインスタンスの最大数を指定します。 インスタンスの最大数を超えない限り、サーバーは CreateNamedPipe を繰り返し呼び出してパイプの追加インスタンスを作成できます。 関数が成功すると、各呼び出しは名前付きパイプ インスタンスのサーバー側にハンドルを返します。

パイプ サーバーがパイプ インスタンスを作成するとすぐに、パイプ クライアントは CreateFile または CallNamedPipe 関数を呼び出して接続できます。 パイプ インスタンスが使用可能な場合、 CreateFile はパイプ インスタンスのクライアント側にハンドルを返します。 パイプのインスタンスが使用できない場合、パイプ クライアントは WaitNamedPipe 関数を使用して、パイプが使用可能になるまで待機できます。

パイプ サーバーは、 ConnectNamedPipe 関数を呼び出すことによって、パイプ クライアントがパイプ インスタンスに接続されているタイミングを判断できます。 パイプ ハンドルがブロッキング待機モードの場合、 ConnectNamedPipe はクライアントが接続されるまで戻りません。

パイプ クライアントとサーバーは、 CallNamedPipe に加えていくつかの関数のいずれかを呼び出して、名前付きパイプの読み取りと書き込みを行うことができます。 これらの関数の動作は、次のように、パイプの種類と、指定したパイプ ハンドルに対して有効なモードによって異なります。

  • ReadFile 関数と WriteFile 関数は、バイト型パイプまたはメッセージ型パイプで使用できます。
  • パイプ ハンドルが重複する操作のために開かれた場合は、 ReadFileEx 関数と WriteFileEx 関数をバイト型パイプまたはメッセージ型パイプと共に使用できます。
  • PeekNamedPipe 関数を使用すると、バイト型パイプまたはメッセージ型パイプの内容を削除せずに読み取ることができます。 PeekNamedPipe は、パイプ インスタンスに関する追加情報を返すこともできます。
  • TransactNamedPipe 関数は、呼び出し元プロセスへのパイプ ハンドルがメッセージ読み取りモードに設定されている場合、メッセージ型の二重パイプで使用できます。 関数は要求メッセージを書き込み、1 回の操作で応答メッセージを読み取り、ネットワーク パフォーマンスを向上させます。

パイプ サーバーは、パイプ クライアントが開始されるまでブロック読み取り操作を実行しないでください。 そうしないと、競合状態が発生する可能性があります。 これは通常、C ランタイム ライブラリの初期化コードなど、継承されたハンドルをロックして調べる必要がある場合に発生します。

クライアントとサーバーがパイプ インスタンスの使用を終了したら、まず FlushFileBuffers 関数を呼び出して、パイプに書き込まれたすべてのバイトまたはメッセージがクライアントによって読み取られるようにする必要があります。 FlushFileBuffers は、 クライアントがパイプからすべてのデータを読み取るまで戻りません。 その後、サーバーは DisconnectNamedPipe 関数を呼び出して、パイプ クライアントへの接続を閉じます。 この関数は、まだ閉じていない場合に、クライアントのハンドルを無効にします。 パイプ内の未読データはすべて破棄されます。 クライアントが切断されると、サーバーは CloseHandle 関数を呼び出して、パイプ インスタンスへのハンドルを閉じます。 または、サーバーは ConnectNamedPipe を使用して、新しいクライアントがパイプのこのインスタンスに接続できるようにします。

プロセスでは、名前付きパイプに関する情報を取得するには、 GetNamedPipeInfo 関数を呼び出します。この関数は、パイプの種類、入力バッファーと出力バッファーのサイズ、作成できるパイプ インスタンスの最大数を返します。 GetNamedPipeHandleState 関数は、パイプ ハンドルの読み取りモードと待機モード、パイプ インスタンスの現在の数、およびネットワーク経由で通信するパイプの追加情報を報告します。 SetNamedPipeHandleState 関数は、パイプ ハンドルの読み取りモードと待機モードを設定します。 リモート サーバーと通信するパイプ クライアントの場合、この関数は、収集する最大バイト数、またはメッセージを送信するまでの最大待機時間も制御します (クライアントのハンドルが書き込みスルー モードを有効にして開かなかったと仮定します)。