2012-12-10 49 views
103

Làm cách nào để viết một đơn giản - tối thiểu cần thiết để nó hoạt động - ứng dụng thử nghiệm minh họa cách sử dụng các Ống IPC/Đặt tên?Ví dụ về các Ống có Tên

Ví dụ, làm thế nào người ta sẽ viết một ứng dụng giao diện điều khiển nơi Chương trình 1 nói "Hello World" Chương trình 2 và Chương trình 2 nhận tin nhắn và trả lời "Roger That" Program 1.

Trả lời

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

Chỉ cần tự hỏi điều gì Line: 16 được coi là vì không có định nghĩa cho 'chậm trễ' trong System.Thread .Tasks –

+1

@JordanTrainor Xin lỗi, nó nằm trong .Net 4.5. Bạn có thể sử dụng 'Thread.Sleep' –

+0

Việc sử dụng Tác vụ trong ví dụ này khá dire. Đó là cú pháp chi tiết và do lập kế hoạch có thể không được thậm chí gần 1000ms. – Gusdor

17

Đối với những người là mới đối với IPC và Named Pipes, tôi đã tìm thấy gói NuGet sau đây là một trợ giúp tuyệt vời.

GitHub: Named Pipe Wrapper for .NET 4.0

Để sử dụng đầu tiên cài đặt gói:

PS> Install-Package NamedPipeWrapper 

Sau đó, một máy chủ ví dụ (sao chép từ liên kết):

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

Ví dụ khách hàng:

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

client.Start(); 

Điều tốt nhất về nó đối với tôi là không giống như câu trả lời được chấp nhận ở đây nó hỗ trợ nhiều khách hàng nói chuyện với một máy chủ duy nhất.

+2

Tôi sẽ không đề nghị gói NuGet này cho sản xuất. Tôi đã thực hiện nó và nó có một số lỗi, chủ yếu là do không thể thực sự biết khi một tin nhắn đã được nhận đầy đủ ở đầu kia của đường ống (dẫn đến kết nối bị hỏng, hoặc kết nối kết thúc quá sớm (kiểm tra mã trên github nếu bạn không tin tưởng tôi, "WaitForPipeDrain" không được gọi khi nó nên), cộng với bạn sẽ có nhiều khách hàng ngay cả khi chỉ có một là lắng nghe bởi vì ... quá nhiều vấn đề). Thật buồn vì nó rất dễ sử dụng. Tôi đã phải xây dựng lại một từ đầu với ít lựa chọn hơn. –

+0

Có điểm tốt, không may là người bảo trì ban đầu đã không cập nhật dự án trong nhiều năm, may mắn thay mặc dù một số nhánh tồn tại hầu hết trong số đó khắc phục các vấn đề bạn thảo luận. –

10

Bạn thực sự có thể ghi vào một đường ống được đặt tên bằng tên của nó, btw.

Mở một lệnh shell as Administrator để có được xung quanh mặc định "Truy cập bị từ chối" lỗi:

echo Hello > \\.\pipe\PipeName