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]);
                }
            }
        }
Esempio n. 2
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);
                    }
                }
            }
        }
Esempio n. 3
0
        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;
                }
            }
        }
Esempio n. 6
0
        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;
                }
            }
        }
Esempio n. 7
0
        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();
            }
        }
Esempio n. 8
0
 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));
 }
Esempio n. 10
0
        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";
            });
        }
Esempio n. 11
0
    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();
            }
        }
    }
Esempio n. 12
0
        // 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}");
                }
            }
        }
Esempio n. 13
0
        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();
        }
Esempio n. 14
0
        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;
                }
            }
        }
Esempio n. 15
0
    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;
            }
        }
    }
Esempio n. 16
0
        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);
                }
            }
        }
Esempio n. 17
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);
            }
        }
Esempio n. 18
0
        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;
                    }
                }
            }
        }
Esempio n. 19
0
        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);
        }