Jak napisać prostą - absolutne minimum potrzebne do działania - aplikację testową, która ilustruje, jak używać IPC / Named Pipes?
Na przykład, jak napisać aplikację konsolową, w której Program 1 mówi „Witaj świecie” do Programu 2, a Program 2 odbiera komunikat i odpowiada „Zrozumiano” do Programu 1.
c#
ipc
named-pipes
Jordan Trainor
źródło
źródło
Thread.Sleep
Task.Factory.StartNew
zTask.Run
.reader
/writer
? Jeśli tak, czy pozbywasz się tylko jednego z nich? Nigdy nie widziałem przykładu, w którym oba są podłączone do tego samego strumienia.Dla kogoś, kto jest nowy w IPC i nazwanych potokach, uważam, że następujący pakiet NuGet jest bardzo pomocny.
GitHub: Named Pipe Wrapper dla .NET 4.0
Aby użyć najpierw zainstaluj pakiet:
Następnie przykładowy serwer (skopiowany z linku):
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();
Przykładowy klient:
var client = new NamedPipeClient<SomeClass>("MyServerPipe"); client.ServerMessage += delegate(NamedPipeConnection<SomeClass> conn, SomeClass message) { Console.WriteLine("Server says: {0}", message.Text); }; client.Start();
Najlepsze w tym jest to, że w przeciwieństwie do przyjętej tutaj odpowiedzi obsługuje wielu klientów rozmawiających z jednym serwerem.
źródło
Tak przy okazji, możesz pisać do nazwanego potoku, używając jego nazwy.
Otwórz powłokę poleceń jako administrator, aby obejść domyślny błąd „Odmowa dostępu”:
źródło
Wypróbuj TcpListener, jeśli wdrażasz w systemie Linux
Ten kod klienta / serwera NamedPipe w obie strony przesyła bajt do serwera.
DotNet Core 2.0 Server ConsoleApp
using System; using System.IO.Pipes; using System.Threading.Tasks; namespace Server { class Program { static void Main(string[] args) { var server = new NamedPipeServerStream("A", PipeDirection.InOut); server.WaitForConnection(); for (int i =0; i < 10000; i++) { var b = new byte[1]; server.Read(b, 0, 1); Console.WriteLine("Read Byte:" + b[0]); server.Write(b, 0, 1); } } } }
Konsola klienta DotNet Core 2.0
using System; using System.IO.Pipes; using System.Threading.Tasks; namespace Client { class Program { public static int threadcounter = 1; public static NamedPipeClientStream client; static void Main(string[] args) { client = new NamedPipeClientStream(".", "A", PipeDirection.InOut, PipeOptions.Asynchronous); client.Connect(); var t1 = new System.Threading.Thread(StartSend); var t2 = new System.Threading.Thread(StartSend); t1.Start(); t2.Start(); } public static void StartSend() { int thisThread = threadcounter; threadcounter++; StartReadingAsync(client); for (int i = 0; i < 10000; i++) { var buf = new byte[1]; buf[0] = (byte)i; client.WriteAsync(buf, 0, 1); Console.WriteLine($@"Thread{thisThread} Wrote: {buf[0]}"); } } public static async Task StartReadingAsync(NamedPipeClientStream pipe) { var bufferLength = 1; byte[] pBuffer = new byte[bufferLength]; await pipe.ReadAsync(pBuffer, 0, bufferLength).ContinueWith(async c => { Console.WriteLine($@"read data {pBuffer[0]}"); await StartReadingAsync(pipe); // read the next data <-- }); } } }
źródło
System Unauthorized Accesss Exception - path is denied