.NETで名前付きパイプを試す(1) - クライアントからサーバにメッセージを送る
.NET Frameworkを使って名前付きパイプでプロセス間通信を実装する方法が気になったので調べています。このエントリはその勉強の記録です。
名前付きパイプを実装するには、NamedPipeServerStreamとNamedPaipeClientStreamを使います。
クラス名にもありますが、名前付きパイプはクライアントサーバ型の通信です。通信するといってもあまり特別なことはなくてFileStreamやMemoryStreamと同じように扱えばOKのようです。Streamに書き込む(=送信)、Streamから読み込む(=受信)といった操作で通信できるようです。
ということでまずはすごく単純なクライアント側のプログラムとサーバ側のプログラムを作ってみます。それぞれの動きは次のようにします。
クライアント側のプログラムの動き
- サーバに接続
- メッセージ(文字列)を送信する
サーバ側のプログラムの動き
- クライアントからの接続を待つ
- メッセージ(文字列)を受信する
実用にはほど遠いですが一旦これを目指します。文字列以外も送る、送受信するなどやりたいことはたくさんありますが、最初は高望みしないことにします。
クライアント側のプログラム
まずはクライアント側。サーバに接続してメッセージを送信します。
// クライアント側 class Program { private static async Task Client() { // ローカルの"testpipe"という名前のパイプのクライアント using (var stream = new NamedPipeClientStream("testpipe")) { // サーバに接続 await stream.ConnectAsync(); // メッセージを送信(書き込み) using (var writer = new StreamWriter(stream)) { Console.WriteLine($"Send"); var message = "あいうえお"; await writer.WriteLineAsync(message); Console.WriteLine($"Sent: {message}"); } } } static void Main(string[] args) { Console.WriteLine("Client"); Client().Wait(); } } // 実行結果 /* Client Send Sent: あいうえお */
コメントとして実行結果ものせていますがサーバ側も動かした場合の実行結果です。
また試していませんが、NamedPipeClientStreamを作るときにサーバ名を指定できるようです。指定しない場合はローカル上のパイプになります。
サーバ側のプログラム
次にサーバ。クライアントからの接続を待ってメッセージを受信します。
// サーバ側 class Program { private static async Task Server() { // "testpipe"という名前のパイプのサーバ using (var stream = new NamedPipeServerStream("testpipe")) { // クライアントからの接続を待つ await stream.WaitForConnectionAsync(); // メッセージを受信(読み込み) using (var reader = new StreamReader(stream)) { Console.WriteLine("Receive"); var message = await reader.ReadLineAsync(); Console.WriteLine($"Received: {message}"); } } } static void Main(string[] args) { Console.WriteLine("Server"); Server().Wait(); } } // 実行結果 /* Server Receive Received: あいうえお */
この2つのプログラムを実行するとクライアントからサーバにメッセージを送信できることが確認できます。
とりあえず送信できたので今回はこのあたりで。
ちなみにソリューションにプロジェクトを2つ入れて同時にデバッグ実行すると楽かもです。