2012-12-10 5 views
103

Wie schreibe ich ein einfaches - nackte Minimum benötigt, damit es funktioniert - Anwendung testen, die zeigt, wie IPC/Named Pipes zu verwenden?Beispiel für Named Pipes

Zum Beispiel, wie würde man eine Konsole-Anwendung schreiben, in dem Programm 1 sagt: „Hallo Welt“ Programm 2 und Programm 2 empfängt Nachricht und Antworten „Roger der“ 1.

Antwort

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

Einfach fragen, was Line: 16 sein sollte, weil es keine Definition ist für ‚Verzögerung‘ in System.Thread .Tasks –

+1

@JordanTrainor Sorry, es ist in .Net 4.5. Sie können 'Thread.Sleep' verwenden –

+0

Die Verwendung von Task in diesem Beispiel ist ziemlich düster. Es ist eine ausführliche Syntax und aufgrund der Planung möglicherweise nicht einmal in der Nähe von 1000ms. – Gusdor

17

Für jemanden zum Programm, die ist neu für IPC und Named Pipes, ich fand das folgende NuGet-Paket eine große Hilfe.

GitHub: Named Pipe Wrapper for .NET 4.0

Zum ersten installieren Sie das Paket verwenden:

PS> Install-Package NamedPipeWrapper 

ein Beispiel Server dann (über den Link kopiert):

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(); 

Beispiel Auftraggeber:

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

client.Start(); 

Das Beste für mich ist, dass es im Gegensatz zur angenommenen Antwort mehrere Clients unterstützt, die mit einem einzelnen Server sprechen.

+2

Ich würde dieses NuGet-Paket für die Produktion nicht empfehlen. Ich habe es implementiert und es hat einige Bugs, hauptsächlich weil ich nicht in der Lage bin zu wissen, wann eine Nachricht vollständig am anderen Ende der Pipe empfangen wurde (führt zu kaputten Verbindungen, oder die Verbindung endet zu früh (überprüfen Sie den Code auf Github, wenn Sie mir nicht vertrauen, "WaitForPipeDrain" wird nicht aufgerufen, wenn es sollte, und Sie haben mehrere Clients, auch wenn nur einer zuhört, weil ... zu viele Probleme). Es ist traurig, weil es wirklich einfach zu bedienen war. Ich musste einen von Grund auf mit weniger Optionen neu erstellen. –

+0

Ja, guter Punkt, leider hat der ursprüngliche Betreuer das Projekt seit Jahren nicht aktualisiert, obwohl glücklicherweise eine Reihe von Gabeln existieren, von denen die meisten die von Ihnen diskutierten Probleme beheben. –

10

Sie können tatsächlich zu einem Named Pipe mit seinem Namen, BTW schreiben.

ein Kommando-Shell als Administrator öffnet um den Standard zu bekommen „Zugriff verweigert“ Fehler:

echo Hello > \\.\pipe\PipeName