Search code examples
c#named-pipes

Named Pipes unexpected result


Have a simple named pipes server:

        static void Main(string[] args)
    {
        StartServer();
        Console.Read();
    }

    static void StartServer()
    {
        Task.Factory.StartNew(() =>
        {
            var server = new NamedPipeServerStream("TestPipes");

            server.WaitForConnection();
            StreamReader reader = new StreamReader(server);
           StreamWriter writer = new StreamWriter(server);

            while (true)
            {

                var line = reader.ReadLine();
            if (line == "Y")
            {

                for (int i = 0; i < 5; i++)
                    writer.WriteLine(i.ToString());
                writer.Flush();

            }

            if (line=="N")
            {
                for (int i = 10; i < 15; i++)
                    writer.WriteLine(i.ToString());
                writer.Flush();
            }   


            }
        });
    }

and very simple client:

static void Main(string[] args)
    {

        //Client
        var client = new NamedPipeClientStream(Environment.MachineName, "TestPipes");

        client.Connect();
        Console.WriteLine($"Connection esteblished at {DateTime.Now}, you may continue");
        StreamReader reader = new StreamReader(client);
        StreamWriter writer = new StreamWriter(client);

        while (true)
        {

            string input = Console.ReadLine();
            if (String.IsNullOrEmpty(input)) continue;
            writer.WriteLine(input);
              writer.Flush();

            string serverString;
            while (reader.Peek() >= 0)
            {
                serverString = reader.ReadLine();
                Console.WriteLine(serverString);

            } 


        }
    }

but for some reason only first command is being completed. for example if I enter 'Y' getting output 'Y' and then when 'N' is entered nothing comes from the server. Need to make it work continuously. Thank you.


Solution

  • That's because in your client you're defining StreamReader reader = new StreamReader(client); outside of the while loop, so on the first iteration when the reader hits the last line, the underlying stream never gets reset, so reader.Peek() >= 0 yields false for subsequent calls.

    Move the declaration of the client reader object inside the while loop:

    var client = new NamedPipeClientStream(Environment.MachineName, "TestPipes");
    client.Connect();
    Console.WriteLine($"Connection esteblished at {DateTime.Now}, you may continue");
    
    StreamWriter writer = new StreamWriter(client);
    while (true)
    {
        StreamReader reader = new StreamReader(client);
        string input = Console.ReadLine();
        if (String.IsNullOrEmpty(input)) continue;
        writer.WriteLine(input);
        writer.Flush();
    
        string serverString;
        while (reader.Peek() >= 0)
        {
            serverString = reader.ReadLine();
            Console.WriteLine(serverString);
        }
    }