2012-12-10 124 views
103

如何編寫一個簡單的 - 工作所需的最低限度 - 說明如何使用IPC /命名管道的測試應用程序?命名管道示例

例如,如何將一個寫一個控制檯應用程序,其中方案一的「Hello World」說要計劃2和計劃2接收消息和回覆「羅傑,」要程序1.

回答

130
using System; 
using System.IO; 
using System.IO.Pipes; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      StartServer(); 
      Task.Delay(1000).Wait(); 


      //Client 
      var client = new NamedPipeClientStream("PipesOfPiece"); 
      client.Connect(); 
      StreamReader reader = new StreamReader(client); 
      StreamWriter writer = new StreamWriter(client); 

      while (true) 
      { 
       string input = Console.ReadLine(); 
       if (String.IsNullOrEmpty(input)) break; 
       writer.WriteLine(input); 
       writer.Flush(); 
       Console.WriteLine(reader.ReadLine()); 
      } 
     } 

     static void StartServer() 
     { 
      Task.Factory.StartNew(() => 
      { 
       var server = new NamedPipeServerStream("PipesOfPiece"); 
       server.WaitForConnection(); 
       StreamReader reader = new StreamReader(server); 
       StreamWriter writer = new StreamWriter(server); 
       while (true) 
       { 
        var line = reader.ReadLine(); 
        writer.WriteLine(String.Join("", line.Reverse())); 
        writer.Flush(); 
       } 
      }); 
     } 
    } 
} 
+0

只是想知道是什麼行:16應該是因爲沒有定義「延遲」在System.Thread 。任務 –

+1

@JordanTrainor對不起,它是在.Net 4.5。你可以使用'Thread.Sleep' –

+0

這個例子中Task的使用非常可怕。它是冗長的語法,由於調度可能不會接近1000毫秒。 – Gusdor

17

有人誰對IPC和命名管道來說是新的,我發現以下NuGet包是一個很好的幫助。

GitHub: Named Pipe Wrapper for .NET 4.0

要使用第一安裝軟件包:

PS> Install-Package NamedPipeWrapper 

然後,一個示例服務器(從鏈接複製):

var server = new NamedPipeServer<SomeClass>("MyServerPipe"); 
server.ClientConnected += delegate(NamedPipeConnection<SomeClass> conn) 
    { 
     Console.WriteLine("Client {0} is now connected!", conn.Id); 
     conn.PushMessage(new SomeClass { Text: "Welcome!" }); 
    }; 

server.ClientMessage += delegate(NamedPipeConnection<SomeClass> conn, SomeClass message) 
    { 
     Console.WriteLine("Client {0} says: {1}", conn.Id, message.Text); 
    }; 

server.Start(); 

實施例的客戶端:

var client = new NamedPipeClient<SomeClass>("MyServerPipe"); 
client.ServerMessage += delegate(NamedPipeConnection<SomeClass> conn, SomeClass message) 
    { 
     Console.WriteLine("Server says: {0}", message.Text); 
    }; 

client.Start(); 

對我來說最好的事情就是不像這裏接受的答案,它支持多個客戶端與單個服務器交談。

+2

我不會推薦這個NuGet包進行生產。我已經實現了它,它有一些錯誤,主要是由於無法真正知道消息在管道的另一端是否完全接收(導致連接斷開或連接過早結束)(請檢查代碼github如果你不信任我,「WaitForPipeDrain」不應該被調用),再加上你將有多個客戶端,即使只有一個人在監聽,因爲......太多問題)。這很難過,因爲它非常易於使用。我不得不從頭開始重建一個選項。 –

+0

是的好點,不幸的是,原來的維護人員多年沒有更新項目,幸運的是,雖然存在大量的分支,其中大部分都會解決您討論的問題。 –

10

您實際上可以使用其名稱btw寫入命名管道。

打開命令shell作爲管理員繞過默認的「訪問被拒絕」的錯誤:

echo Hello > \\.\pipe\PipeName