パイプの作成と接続プロセス間通信を行うにあたって、Windowメッセージが最も手軽な手段であることは異論のないところでしょう。相手側からしても「接続してくるまで待機」といった操作を行う必要もありません。Windowメッセージがあらゆる場面でも使用できるというと、必ずしもそうとはいえません。した場合はWindowメッセージを使いにくいと感じるかもしれません。メッセージを送受信すること自体ができなくなりますから、名前付きパイプのような別の通信手段を考える必要があります。クライアントがそれに接続することで成立しています。名前付きパイプにはWindowsのセキュリティモデルに統合されているという特徴があります。これはオブジェクトにセキュリティ記述子を指定して、任意のアカウントからのアクセスを制限するというものです。名前付きパイプにセキュリティ記述子を指定すれば、アクセスするクライアントを制限できます。名前付きパイプのサーバーはクライアントのトークンを偽装できます。オブジェクトへのアクセスをクライアントとして行いたい場合に便利です。プロセス間通信においてはWinsockより名前付きパイプの方が向いているといえるでしょう。逆にインターネット上の通信では、ソケットという既知の概念を使用するWinsockが便利です。名前付きパイプ(以下パイプ)を作成するには、CreateNamedPipeを呼び出します。lpSecurityAttributes);lpNameは、作成するパイプの名前を指定します。名前の形式は\\.\pipe\pipenameであり、pipenameの部分には任意の文字列を指定できます。dwOpenModeは、アクセスモードなどを指定します。PIPE_ACCESS_OUTBOUNDを指定した場合は書き込み(クライアントは読み取りのみ)が可能になります。dwPipeModeは、パイプのタイプモードを指定します。通常は、バイトストリームのデータを扱うことを示すPIPE_TYPE_BYTEでよいと思われます。nMaxInstancesは、パイプに対して作成できるインスタンスの最大数を指定します。PIPE_UNLIMITED_INSTANCESを指定すれば、リソースの許す限りインスタンスを作成できるとされています。nOutBufferSizeは、出力バッファとして予約すべきバイト数を指定します。nInBufferSizeは、入力バッファとして予約すべきバイト数を指定します。これらバイト数は参考として使用されるだけで、実際にこの数だけバッファが割り当てられるとは限りません。nDefaultTimeOutは、クライアントが呼び出すWaitNamedPipeのタイムアウト値をミリ秒単位で指定します。lpSecurityAttributesは、パイプに設定するセキュリティ記述子を指定します。パイプに対して作成できるインスタンスという言葉は、少し分かりにくいところがあるかもしれません。作成されるのはパイプの1つ目のインスタンスです。クライアントがパイプへの接続を行おうとした場合、この1つ目のインスタンスと接続されます。今度はパイプの2つ目のインスタンスが作成されます。1つ目のインスタンスで扱われるデータが、2つ目のインスタンスに影響を与えることはありません。nMaxInstancesが2である場合は、同時に作成できるインスタンスは2つ限界であるため、これは失敗します。それでは、3つ目のクライアントは決してインスタンスに接続できないかというと、そういうわけではありません。このインスタンスに3つ目のクライアントは接続できます。簡単に言えば、nMaxInstancesとは同時に接続できるクライアントの数ということになります。パイプを作成したサーバーは、ConnectNamedPipeでクライアントからの接続を待ちます。lpOverlapped);hNamedPipeは、CreateNamedPipeで作成したパイプのハンドルを指定します。lpOverlappedは、OVERLAPPED構造体のアドレスを指定します。これはConnectNamedPipeで待機するのではなく、イベントオブジェクト(OVERLAPPED.hEvent)を使用して待機を行いたい場合に使用します。この場合、ConnectNamedPipeは直ちに制御を返し、別途GetOverlappedResultやWaitForMultipleObjectsを呼び出すことになるでしょう。クライアントが接続してくるまで待機したい場合は、NULLを指定します。それではまず、サーバーのコードを示します。TEXT("パイプの作成に失敗しました。TEXT("終了します。0;}CreateNamedPipeの第2引数がPIPE_ACCESS_DUPLEXであることから、このパイプは読み取りと書き込みに使用できます。第4引数が1であることから、パイプに同時に接続できるクライアントは1つのみです。パイプを作成したら、クライアントがパイプに接続できるようにConnectNamedPipeを呼び出します。第2引数がNULLであるため、クライアントが接続をしない限り関数は制御を返しません。関数が制御を返したら、ReadFileを呼び出してクライアントからデータが書き込まれるまで待機します。ReadFileによる待機を感じることはないでしょう。今回は簡単のため、取得したデータをそのまま返すようにしています。実際の開発では暗号化に使用する鍵を双方に持たせるなど、意味のあるデータ交換を行うべきです。続いて、クライアントのコードを示します。TEXT("パイプへの接続に失敗しました。0;}クライアントはCreateFileを呼び出すことでパイプに接続できます。第1引数は接続するパイプの名前であり、サーバーがSamplePipeという文字列を指定していたため、同じ文字列を指定します。.の部分にはサーバーが存在するコンピュータ名を指定できますが、クライアントとサーバーが同じコンピュータに存在する場合は.で構いません。サーバーはパイプをPIPE_ACCESS_DUPLEXで作成したため、パイプは読み書きの両方が可能です。この場合はCreateFileの第2引数に、GENERIC_READとGENERIC_WRITEを指定します。サーバーからの応答をReadFileで取得します。"sample-data"という文字列が返ったら成功です。