public async Task PingPong_Async() { // Create names for two pipes string outName = Path.GetRandomFileName(); string inName = Path.GetRandomFileName(); // Create the two named pipes, one for each direction, then create // another process with which to communicate using (var outbound = new NamedPipeServerStream(outName, PipeDirection.Out)) using (var inbound = new NamedPipeClientStream(".", inName, PipeDirection.In)) using (RemoteInvoke(PingPong_OtherProcess, outName, inName)) { // Wait for both pipes to be connected await Task.WhenAll(outbound.WaitForConnectionAsync(), inbound.ConnectAsync()); // Repeatedly write then read a byte to and from the other process var data = new byte[1]; for (byte i = 0; i < 10; i++) { data[0] = i; await outbound.WriteAsync(data, 0, data.Length); data[0] = 0; int received = await inbound.ReadAsync(data, 0, data.Length); Assert.Equal(1, received); Assert.Equal(i, data[0]); } } }
public async Task MultipleWaitingClients_ServerServesOneAtATime(int numClients) { string name = GetUniquePipeName(); using (NamedPipeServerStream server = new NamedPipeServerStream(name)) { var clients = new List <Task>(from i in Enumerable.Range(0, numClients) select ConnectClientAndReadAsync()); while (clients.Count > 0) { Task <Task> firstClient = Task.WhenAny(clients); await new Task[] { ServerWaitReadAndWriteAsync(), firstClient }.WhenAllOrAnyFailed(); clients.Remove(firstClient.Result); } async Task ServerWaitReadAndWriteAsync() { await server.WaitForConnectionAsync(); await server.WriteAsync(new byte[1], 0, 1); Assert.Equal(1, await server.ReadAsync(new byte[1], 0, 1)); server.Disconnect(); } async Task ConnectClientAndReadAsync() { using (var npcs = new NamedPipeClientStream(name)) { await npcs.ConnectAsync(); Assert.Equal(1, await npcs.ReadAsync(new byte[1], 0, 1)); await npcs.WriteAsync(new byte[1], 0, 1); } } } }
private async Task <JObject> SendAndReceive(StreamlabsOBSRequest request) { await this.idSempahoreLock.WaitAsync(); request.ID = this.currentID; this.currentID++; JObject result = new JObject(); try { JObject requestJObj = JObject.FromObject(request); using (NamedPipeClientStream namedPipeClient = new NamedPipeClientStream(ConnectionString)) { string requestString = requestJObj.ToString(Formatting.None); byte[] requestBytes = Encoding.UTF8.GetBytes(requestString); await Task.WhenAny(Task.Run(async() => { namedPipeClient.Connect(); await namedPipeClient.WriteAsync(requestBytes, 0, requestBytes.Length); byte[] responseBytes = new byte[1000000]; int count = await namedPipeClient.ReadAsync(responseBytes, 0, responseBytes.Length); string responseString = Encoding.ASCII.GetString(responseBytes, 0, count); result = JObject.Parse(responseString); }), Task.Delay(5000)); } } catch (Exception ex) { Logger.Log(ex); } finally { this.idSempahoreLock.Release(); } return(result); }
public async Task ClonedClient_ActsAsOriginalClient() { byte[] msg1 = new byte[] { 5, 7, 9, 10 }; byte[] received1 = new byte[] { 0, 0, 0, 0 }; using (NamedPipePair pair = CreateNamedPipePair()) { pair.Connect(); NamedPipeServerStream server = pair.serverStream; if (pair.writeToServer) { using (NamedPipeClientStream client = new NamedPipeClientStream(PipeDirection.In, false, true, pair.clientStream.SafePipeHandle)) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Assert.Equal(1, client.NumberOfServerInstances); } Task <int> clientTask = client.ReadAsync(received1, 0, received1.Length); server.Write(msg1, 0, msg1.Length); int receivedLength = await clientTask; Assert.Equal(msg1.Length, receivedLength); Assert.Equal(msg1, received1); } } else { using (NamedPipeClientStream client = new NamedPipeClientStream(PipeDirection.Out, false, true, pair.clientStream.SafePipeHandle)) { Task clientTask = client.WriteAsync(msg1, 0, msg1.Length); int receivedLength = server.Read(received1, 0, msg1.Length); Assert.Equal(msg1.Length, receivedLength); Assert.Equal(msg1, received1); await clientTask; } } } }
public async Task ClonedClient_ActsAsOriginalClient() { byte[] msg1 = new byte[] { 5, 7, 9, 10 }; byte[] received1 = new byte[] { 0, 0, 0, 0 }; using StreamPair streams = await CreateConnectedStreamsAsync(); (Stream writeable, Stream readable) = GetReadWritePair(streams); if (writeable is NamedPipeServerStream server) { using (NamedPipeClientStream client = new NamedPipeClientStream(PipeDirection.In, false, true, ((NamedPipeClientStream)readable).SafePipeHandle)) { if (OperatingSystem.IsWindows()) { Assert.Equal(1, client.NumberOfServerInstances); } Task <int> clientTask = client.ReadAsync(received1, 0, received1.Length); server.Write(msg1, 0, msg1.Length); int receivedLength = await clientTask; Assert.Equal(msg1.Length, receivedLength); Assert.Equal(msg1, received1); } } else { using (NamedPipeClientStream client = new NamedPipeClientStream(PipeDirection.Out, false, true, ((NamedPipeClientStream)writeable).SafePipeHandle)) { Task clientTask = client.WriteAsync(msg1, 0, msg1.Length); int receivedLength = readable.Read(received1, 0, msg1.Length); Assert.Equal(msg1.Length, receivedLength); Assert.Equal(msg1, received1); await clientTask; } } }
private void PipeThreadFunc() { while (!cts.IsCancellationRequested) { if (!pipe.IsConnected) { Debug.WriteLine("Connecting to the pipe."); try { pipe.Connect(0); Debug.WriteLine("Connected to the pipe. Readmode: " + pipe.ReadMode); pipe.ReadMode = PipeTransmissionMode.Message; Debug.WriteLine("Set the message read mode."); } catch (Exception e) when(e is TimeoutException || e is IOException) { Debug.WriteLine("Idling for 1 second."); cts.Token.WaitHandle.WaitOne(TimeSpan.FromSeconds(1)); continue; } } // Connected to the pipe. try { var buf = new byte[256]; var task = pipe.ReadAsync(buf, 0, 256, cts.Token); task.Wait(); if (task.Result == 0) { // The pipe was closed. Debug.WriteLine("Pipe end of stream reached."); continue; } if (buf[0] != task.Result) { Debug.WriteLine("Received an incorrect number of bytes (" + task.Result + ", expected " + buf[0] + ")."); continue; } ParseMessage(buf); } catch (AggregateException e) { foreach (var ex in e.InnerExceptions) { if (ex is TaskCanceledException) { return; } } Debug.WriteLine("Error reading from the pipe:"); foreach (var ex in e.InnerExceptions) { Debug.WriteLine("- " + ex.GetType().Name + ": " + ex.Message); } Debug.WriteLine("Idling for 1 second."); cts.Token.WaitHandle.WaitOne(TimeSpan.FromSeconds(1)); continue; } catch (Exception e) { Debug.WriteLine("Error reading from the pipe: " + e.Message); Debug.WriteLine("Idling for 1 second."); cts.Token.WaitHandle.WaitOne(TimeSpan.FromSeconds(1)); continue; } } }
private void ProcessMessages() { var incomingMessage = new byte[BufferSize]; _isBufferReady.Set(); try { // tell others that we are indeed processing messages. _isProcessingMessages.Set(); do { // we need to wait for the buffer to become available. _isBufferReady.WaitOne(); // now we claim the buffer _isBufferReady.Reset(); Task <int> readTask; readTask = _pipe.ReadAsync(incomingMessage, 0, BufferSize); readTask.ContinueWith( antecedent => { if (antecedent.IsCanceled || antecedent.IsFaulted || !IsConnected) { if (antecedent.IsCanceled) { Logger.Message("Client/Session ReadTask is Cancelled"); } if (antecedent.IsFaulted) { Logger.Message("Client/Session ReadTask is Faulted : {0}", antecedent.Exception.GetType()); } Disconnect(); return; } if (antecedent.Result > 0) { var rawMessage = Encoding.UTF8.GetString(incomingMessage, 0, antecedent.Result); var responseMessage = new UrlEncodedMessage(rawMessage); var rqid = responseMessage["rqid"].ToInt32(); // lazy log the response (since we're at the end of this task) Logger.Message("Response:[{0}]{1}".format(rqid, responseMessage.ToSmallerString())); try { var queue = ManualEventQueue.GetQueue(rqid); if (queue != null) { queue.Enqueue(responseMessage); } //else { // GS01 : Need to put in protocol version detection. //} } catch { } } // it's ok to let the next readTask use the buffer, we've got the data out & queued. _isBufferReady.Set(); }).AutoManage(); // this wait just makes sure that we're only asking for one message at a time // but does not throttle the messages themselves. // readTask.Wait(); } while (IsConnected); } catch (Exception e) { Logger.Message("Connection Terminating with Exception {0}/{1}", e.GetType(), e.Message); } finally { Logger.Message("In ProcessMessages/Finally"); Disconnect(); } }
public async Task <int> ReceiveBufferedResponseAsync(NamedPipeClientStream client, byte[] buffer, CancellationToken cancellationToken) { return(await client.ReadAsync(buffer, 0, buffer.Length, cancellationToken)); }
public Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { return(stream.ReadAsync(buffer, offset, count, cancellationToken)); }
private void pipeReader(CancellationToken aCancellationToken) { while (!aCancellationToken.IsCancellationRequested && _pipeClient != null && _pipeClient.IsConnected) { var buffer = new byte[4096]; string msg = string.Empty; var len = -1; while (len < 0 || (len == buffer.Length && buffer[4095] != '\0')) { try { var waiter = _pipeClient.ReadAsync(buffer, 0, buffer.Length); while (!waiter.GetAwaiter().IsCompleted) { if (!_pipeClient.IsConnected) { return; } Thread.Sleep(10); } len = waiter.GetAwaiter().GetResult(); } catch { continue; } if (len > 0) { msg += Encoding.ASCII.GetString(buffer, 0, len); } } var parsed = _parser.Deserialize(msg); if (parsed == null) { continue; } switch (parsed) { case StartScanning s1: foreach (DeviceSimulator dev in tabs.Values) { var devAdded = new DeviceAdded(); devAdded.Name = dev.Name; devAdded.Id = dev.Id; devAdded.HasLinear = dev.HasLinear; devAdded.HasVibrator = dev.HasVibrator; devAdded.HasRotator = dev.HasRotator; _msgQueue.Enqueue(devAdded); } _msgQueue.Enqueue(new FinishedScanning()); break; case StopScanning s1: break; case StopDevice sd: foreach (DeviceSimulator dev in tabs.Values) { if (dev == null || dev.Id != sd.Id) { return; } Dispatcher.Invoke(() => { if (dev.DeviceHasVibrator.IsChecked.GetValueOrDefault(false)) { dev.VibratorSpeed.Value = 0; } if (dev.DeviceHasRotator.IsChecked.GetValueOrDefault(false)) { dev.RotatorSpeed.Value = 0; } if (dev.DeviceHasLinear.IsChecked.GetValueOrDefault(false)) { // Complicated stuff: position stays the same } }); } break; case Vibrate v: foreach (DeviceSimulator dev in tabs.Values) { if (dev == null || dev.Id != v.Id) { return; } if (dev.HasVibrator) { Dispatcher.Invoke(() => { dev.VibratorSpeed.Value = Math.Min(v.Speed, 1) * dev.VibratorSpeed.Maximum; }); } } break; case Linear l: foreach (DeviceSimulator dev in tabs.Values) { if (dev == null || dev.Id != l.Id) { return; } if (dev.HasLinear) { dev.LinearTargetPosition = Math.Min(l.Position, 99); dev.LinearSpeed = Math.Min(l.Speed, 99); } } break; case Rotate r: foreach (DeviceSimulator dev in tabs.Values) { if (dev == null || dev.Id != r.Id) { return; } if (dev.HasRotator) { Dispatcher.Invoke(() => { dev.RotatorSpeed.Value = (Convert.ToDouble(Math.Min(r.Speed, 99)) / 100) * dev.RotatorSpeed.Maximum; dev.RotatorSpeed.Foreground = r.Clockwise ? Brushes.Red : Brushes.GreenYellow; }); } } break; case Ping p: _msgQueue.Enqueue(new Ping()); break; default: break; } } if (_pipeClient != null && _pipeClient.IsConnected) { _pipeClient.Close(); } _pipeClient = null; Dispatcher.Invoke(() => { Connect.Content = "Connect"; }); }
public static void ClientPInvokeChecks() { using (NamedPipeServerStream server = new NamedPipeServerStream("foo", PipeDirection.In)) { using (NamedPipeClientStream client = new NamedPipeClientStream(".", "foo", PipeDirection.Out)) { Task serverTask = DoServerOperationsAsync(server); client.Connect(); Assert.False(client.CanRead); Assert.False(client.CanSeek); Assert.False(client.CanTimeout); Assert.True(client.CanWrite); Assert.False(client.IsAsync); Assert.True(client.IsConnected); if (Interop.PlatformDetection.OperatingSystem == Interop.OperatingSystem.Windows) { Assert.Equal(0, client.OutBufferSize); } else { Assert.Throws <PlatformNotSupportedException>(() => client.OutBufferSize); } Assert.Equal(PipeTransmissionMode.Byte, client.ReadMode); Assert.NotNull(client.SafePipeHandle); Assert.Equal(PipeTransmissionMode.Byte, client.TransmissionMode); client.Write(new byte[] { 123 }, 0, 1); client.WriteAsync(new byte[] { 124 }, 0, 1).Wait(); if (Interop.PlatformDetection.OperatingSystem == Interop.OperatingSystem.Windows) { client.WaitForPipeDrain(); } else { Assert.Throws <PlatformNotSupportedException>(() => client.WaitForPipeDrain()); } client.Flush(); serverTask.Wait(); } } using (NamedPipeServerStream server = new NamedPipeServerStream("foo", PipeDirection.Out)) { using (NamedPipeClientStream client = new NamedPipeClientStream(".", "foo", PipeDirection.In)) { Task serverTask = DoServerOperationsAsync(server); client.Connect(); if (Interop.PlatformDetection.OperatingSystem == Interop.OperatingSystem.Windows) { Assert.Equal(0, client.InBufferSize); } else { Assert.Throws <PlatformNotSupportedException>(() => client.InBufferSize); } byte[] readData = new byte[] { 0, 1 }; Assert.Equal(1, client.Read(readData, 0, 1)); Assert.Equal(1, client.ReadAsync(readData, 1, 1).Result); Assert.Equal(123, readData[0]); Assert.Equal(124, readData[1]); serverTask.Wait(); } } }
// Returns: // // * null if there is no listener associated with the file. // * file length immediately after flushing (the flushing and the grabbing of the file length are // done atomically) if there is a listener and the file was successfully flushed. // // Throws in all other cases. For example: // // * The remote writer failed to flush because disk is full. // * The remote writer sent invalid response to our request. // * Pipe permission error. public static async Task <long?> FlushAsync(IReadOnlyCollection <byte> fileId, bool flushToDisk) { if (fileId == null) { throw new ArgumentNullException(nameof(fileId)); } while (true) { using (var pipe = new NamedPipeClientStream(".", PipeName(fileId), PipeDirection.InOut, PipeOptions.Asynchronous | PipeOptions.WriteThrough)) { await s_connect.LockAsync(); try { // NamedPipeClientStream has an awful API. It doesn't allow us to bail early if there is no pipe and // to wait indefinitely if there is (this can be done with Win32 API). So we do it manually with // a mutex existence check and a loop. We create this mutex together with the pipe to serve as // a marker of the pipe's existence. It's difficult to use the pipe itself as such marker because // server pipes disappear after accepting and serving a request and there may be a short gap before // we create new server connections. if (Mutex.TryOpenExisting(MutexName(fileId), MutexRights.Synchronize, out Mutex mutex)) { mutex.Dispose(); } else { return(null); } // The timeout is meant to avoid waiting forever if the pipe disappears between the moment // we have verified its existence and our attempt to connect to it. We use a mutex to // restrict the number of simultaneous ConnectAsync() because ConnectAsync() blocks a task // thread for the whole duration of its execution. Without the mutex, WaitAsync() calls // could block all task threads. await pipe.ConnectAsync(100); } catch (TimeoutException) { continue; } catch (IOException) { continue; } finally { s_connect.Unlock(runNextSynchronously: false); } var buf = new byte[UInt64LE.Size]; if (flushToDisk) { buf[0] = 1; } try { await pipe.WriteAsync(buf, 0, 1); await pipe.FlushAsync(); if (await pipe.ReadAsync(buf, 0, UInt64LE.Size) != UInt64LE.Size) { continue; } } catch { continue; } int offset = 0; ulong res = UInt64LE.Read(buf, ref offset); if (res < long.MaxValue) { return((long)res); } if (res == ulong.MaxValue) { throw new IOException("Remote writer failed to flush"); } throw new Exception($"Invalid Flush response: {res}"); } } }
private static async void Test1() { Console.WriteLine("---Test1---"); NamedPipeClientStream client = PrepareClient(); //Request request = new Request() //{ // MethodName = "cl.sensor.get-last-values", // Number = 1, // Params = new string[] // { // "1", // "2", // "11", // "22", // "3" // } //};1. cl.device.get-list Request request = new Request() { MethodName = "cl.device.get-list", Number = 1, Params = null }; // Request request = new Request() // { // MethodName = "cl.device.get-device-sensors", // Number = 4, // Params = new string[] // { // "vid<6940>pid<787515>serial<\\\\.\\HID#VID_1B1C&PID_0C04#6&F9B17DA&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}0>index<0>", } // "2", // } // "11", // "22", // "3" // } //}; // Request request = new Request() // { // MethodName = "cl.sensor.get-last-values", // Number = 4, // Params = new string[] // { // "vid<6940>pid<787515>serial<\\\\.\\HID#VID_1B1C&PID_0C04#6&F9B17DA&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}0>index<0>senstype<Fan>sensindex<1>", } //// "2", } //// "11", //// "22", //// "3" ////} // }; string serialised = JsonConvert.SerializeObject(request); byte[] messageBytes = Encoding.UTF8.GetBytes(serialised); await client.WriteAsync(messageBytes, 0, messageBytes.Length); StringBuilder messageBuilder = new StringBuilder(); string messageChunk = string.Empty; byte[] messageBuffer = new byte[5]; do { await client.ReadAsync(messageBuffer, 0, messageBuffer.Length); messageChunk = Encoding.UTF8.GetString(messageBuffer); messageBuilder.Append(messageChunk); messageBuffer = new byte[messageBuffer.Length]; }while (!client.IsMessageComplete); Console.WriteLine(messageBuilder.ToString()); Console.WriteLine("---Test1 competed---"); Console.WriteLine(); }
private async Task <string> ProcessRequest(string message) { var dataBuffer = Encoding.ASCII.GetBytes(message); var dataSize = dataBuffer.Length; if (dataSize == 0) { return(null); } using (var pipe = new NamedPipeClientStream(m_serverName, m_pipeName, PipeDirection.InOut, PipeOptions.Asynchronous | PipeOptions.WriteThrough)) { try { await Task.Run(() => pipe.Connect(500)); } catch (TimeoutException e) { throw new PipeServerNotFoundException(e.Message, e); } pipe.ReadMode = PipeTransmissionMode.Message; const int cBufferSize = 4096; try { var dataSizeBuffer = BitConverter.GetBytes(dataSize); await pipe.WriteAsync(dataSizeBuffer, 0, dataSizeBuffer.Length); using (var stream = new MemoryStream(dataBuffer)) await CopyStream(stream, pipe, dataSize, cBufferSize); await pipe.FlushAsync(); dataSizeBuffer = new byte[sizeof(Int32)]; var bytesRead = await pipe.ReadAsync(dataSizeBuffer, 0, sizeof(Int32)); if (bytesRead <= 0) { throw new PipeServerBrokenPipeException(); } dataSize = BitConverter.ToInt32(dataSizeBuffer, 0); if (dataSize <= 0) { return(null); } using (var stream = new MemoryStream(dataSize)) { if (!await CopyStream(pipe, stream, dataSize, cBufferSize)) { throw new PipeServerBrokenPipeException(); } var resultBuffer = stream.GetBuffer(); var decoder = Encoding.ASCII.GetDecoder(); var charCount = decoder.GetCharCount(resultBuffer, 0, dataSize, false); var charResultBuffer = new char[charCount]; decoder.GetChars(resultBuffer, 0, dataSize, charResultBuffer, 0, false); decoder.Reset(); return(new string(charResultBuffer)); } } catch (IOException ex) { // Console.WriteLine(ex.Message); // NOTE: This is not relyable, but will do for now if (ex.Message.Contains("Pipe is broken")) { throw new PipeServerBrokenPipeException(); } throw; } } }
public static async Task ClientPInvokeChecks() { using (NamedPipeServerStream server = new NamedPipeServerStream("foo", PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.None, 4096, 4096)) { using (NamedPipeClientStream client = new NamedPipeClientStream(".", "foo", PipeDirection.Out)) { Task serverTask = DoServerOperationsAsync(server); client.Connect(); Assert.False(client.CanRead); Assert.False(client.CanSeek); Assert.False(client.CanTimeout); Assert.True(client.CanWrite); Assert.False(client.IsAsync); Assert.True(client.IsConnected); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Assert.Equal(0, client.OutBufferSize); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { Assert.True(client.OutBufferSize > 0); } else { Assert.Throws <PlatformNotSupportedException>(() => client.OutBufferSize); } Assert.Equal(PipeTransmissionMode.Byte, client.ReadMode); Assert.NotNull(client.SafePipeHandle); Assert.Equal(PipeTransmissionMode.Byte, client.TransmissionMode); client.Write(new byte[] { 123 }, 0, 1); await client.WriteAsync(new byte[] { 124 }, 0, 1); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { client.WaitForPipeDrain(); } else { Assert.Throws <PlatformNotSupportedException>(() => client.WaitForPipeDrain()); } client.Flush(); await serverTask; } } using (NamedPipeServerStream server = new NamedPipeServerStream("foo", PipeDirection.Out)) { using (NamedPipeClientStream client = new NamedPipeClientStream(".", "foo", PipeDirection.In)) { Task serverTask = DoServerOperationsAsync(server); client.Connect(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Assert.Equal(0, client.InBufferSize); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { Assert.True(client.InBufferSize > 0); } else { Assert.Throws <PlatformNotSupportedException>(() => client.InBufferSize); } byte[] readData = new byte[] { 0, 1 }; Assert.Equal(1, client.Read(readData, 0, 1)); Assert.Equal(1, client.ReadAsync(readData, 1, 1).Result); Assert.Equal(123, readData[0]); Assert.Equal(124, readData[1]); await serverTask; } } }
private static async Task RunClient() { Console.WriteLine("Initiating client, looking for server..."); // set up a message to send string messageText = "Sample text message!"; int bytesRead; // set up the named pipe client and close it when complete using (NamedPipeClientStream clientPipe = new NamedPipeClientStream(".", "mypipe", PipeDirection.InOut, PipeOptions.None)) { // connect to the server stream await clientPipe.ConnectAsync(); // set the read mode to message clientPipe.ReadMode = PipeTransmissionMode.Message; // write the message ten times for (int i = 0; i < 10; i++) { Console.WriteLine($"Sending message: {messageText}"); byte[] messageBytes = Encoding.Unicode.GetBytes(messageText); // check and write the message if (clientPipe.CanWrite) { await clientPipe.WriteAsync( messageBytes, 0, messageBytes.Length); await clientPipe.FlushAsync(); // wait till it is read clientPipe.WaitForPipeDrain(); } // set up a buffer for the message bytes messageBytes = new byte[256]; do { // collect the message bits in the stringbuilder StringBuilder message = new StringBuilder(); // read all of the bits until we have the // complete response message do { // read from the pipe bytesRead = await clientPipe.ReadAsync( messageBytes, 0, messageBytes.Length); // if we got something, add it to the message if (bytesRead > 0) { message.Append( Encoding.Unicode.GetString(messageBytes, 0, bytesRead)); Array.Clear(messageBytes, 0, messageBytes.Length); } }while (!clientPipe.IsMessageComplete); // set to zero as we have read the whole message bytesRead = 0; Console.WriteLine($" Received message: {message.ToString()}"); }while (bytesRead != 0); } } }
public static async Task ClientAllReadyConnectedThrows() { using (NamedPipeServerStream server = new NamedPipeServerStream("testServer1", PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) using (NamedPipeClientStream client = new NamedPipeClientStream(".", "testServer1", PipeDirection.InOut, PipeOptions.Asynchronous)) { byte[] buffer = new byte[] { 0, 0, 0, 0 }; Task clientConnect1 = client.ConnectAsync(); server.WaitForConnection(); await clientConnect1; Assert.True(client.IsConnected); Assert.True(server.IsConnected); Assert.Throws<InvalidOperationException>(() => client.Connect()); var ctx = new CancellationTokenSource(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) // [ActiveIssue(812, PlatformID.AnyUnix)] - the cancellation token is ignored after the operation is initiated, due to base Stream's implementation { Task clientReadToken = client.ReadAsync(buffer, 0, buffer.Length, ctx.Token); ctx.Cancel(); await Assert.ThrowsAnyAsync<OperationCanceledException>(() => clientReadToken); } ctx.Cancel(); Assert.True(client.ReadAsync(buffer, 0, buffer.Length, ctx.Token).IsCanceled); var ctx1 = new CancellationTokenSource(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) // [ActiveIssue(812, PlatformID.AnyUnix)] - the cancellation token is ignored after the operation is initiated, due to base Stream's implementation { Task serverReadToken = server.ReadAsync(buffer, 0, buffer.Length, ctx1.Token); ctx1.Cancel(); await Assert.ThrowsAnyAsync<OperationCanceledException>(() => serverReadToken); } ctx1.Cancel(); Assert.True(server.ReadAsync(buffer, 0, buffer.Length, ctx1.Token).IsCanceled); } }
public async Task ClonedClient_ActsAsOriginalClient() { byte[] msg1 = new byte[] { 5, 7, 9, 10 }; byte[] received1 = new byte[] { 0, 0, 0, 0 }; using (NamedPipePair pair = CreateNamedPipePair()) { pair.Connect(); NamedPipeServerStream server = pair.serverStream; if (pair.writeToServer) { using (NamedPipeClientStream client = new NamedPipeClientStream(PipeDirection.In, false, true, pair.clientStream.SafePipeHandle)) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Assert.Equal(1, client.NumberOfServerInstances); } Task<int> clientTask = client.ReadAsync(received1, 0, received1.Length); server.Write(msg1, 0, msg1.Length); int receivedLength = await clientTask; Assert.Equal(msg1.Length, receivedLength); Assert.Equal(msg1, received1); } } else { using (NamedPipeClientStream client = new NamedPipeClientStream(PipeDirection.Out, false, true, pair.clientStream.SafePipeHandle)) { Task clientTask = client.WriteAsync(msg1, 0, msg1.Length); int receivedLength = server.Read(received1, 0, msg1.Length); Assert.Equal(msg1.Length, receivedLength); Assert.Equal(msg1, received1); await clientTask; } } } }
private static async Task <int> Main(string[] args) { var client = false; string name = null; string user = null; string file = null; var options = new OptionSet { { "client|connect|c", "Connect to existing pipe as client", c => client = c != null }, { "server|s", "Create a client as server", c => client = c == null }, { "name|n=", "Named pipe name", n => name = n }, { "username|user|u=", "User name to enforce", u => user = u }, { "file|f=", "File to watch and echo", f => file = f }, }; var remaining = options.Parse(args); if (remaining.Count > 0 && name == null) { name = remaining[0]; remaining.RemoveAt(0); } if (remaining.Count > 0) { Console.Error.WriteLine($"Unknown argument: {remaining[0]}"); return(1); } if (string.IsNullOrEmpty(name)) { Console.Error.WriteLine("Missing required argument --name"); return(1); } if (client) { using (var stream = new NamedPipeClientStream(".", name, PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Impersonation)) { await stream.ConnectAsync(); stream.WriteByte(42); using (var output = Console.OpenStandardOutput()) { while (true) { byte[] length = new byte[8]; var read = await stream.ReadAsync(length, 0, length.Length); if (read == 0) { return(0); } if (read != length.Length) { Console.Error.WriteLine( $"Failed to read length, only got {read} bytes, expected {length.Length}"); return(2); } byte[] buffer = new byte[1024]; long target = BitConverter.ToInt64(length); long total = 0; while (total < target) { read = await stream.ReadAsync(buffer, 0, (int)Math.Min(buffer.Length, target - total)); if (read == 0) { Console.Error.WriteLine($"Expected {target} found {total} bytes..."); return(2); } total += read; await output.WriteAsync(buffer, 0, read); } } } } } else { using (var stream = new NamedPipeServerStream(name, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.None)) { await stream.WaitForConnectionAsync(); if (stream.ReadByte() != 42) { Console.Error.WriteLine($"Missing magic header value"); return(1); } if (!String.IsNullOrEmpty(user) && !String.Equals(user, stream.GetImpersonationUserName(), StringComparison.Ordinal)) { Console.Error.WriteLine( $"Connection from disallowed username: {stream.GetImpersonationUserName()}"); return(1); } async Task EchoFile(Stream source, Stream target) { await target.WriteAsync(BitConverter.GetBytes((long)source.Length)); await source.CopyToAsync(target); } if (file != null) { var dir = Path.GetDirectoryName(Path.GetFullPath(file)); var filename = Path.GetFileName(file); using (var watcher = new FileSystemWatcher(dir, filename) { EnableRaisingEvents = true, }) { TaskCompletionSource <string> changed = new TaskCompletionSource <string>(); watcher.Changed += (o, e) => { switch (e.ChangeType) { case WatcherChangeTypes.Changed: case WatcherChangeTypes.Created: changed.TrySetResult(e.FullPath); break; } }; using (var fileStream = File.OpenRead(file)) { await EchoFile(fileStream, stream); } while (true) { var path = await changed.Task; Interlocked.Exchange(ref changed, new TaskCompletionSource <string>()); FileStream fileStream = null; while (!changed.Task.IsCompleted && fileStream == null) { try { fileStream = File.OpenRead(path); } catch (IOException) { await Task.Delay(TimeSpan.FromMilliseconds(500)); } } using (fileStream) { await EchoFile(fileStream, stream); } } } } else { await EchoFile(Console.OpenStandardInput(), stream); } } } return(0); }