2012-12-10 152 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