0

I have two windows applications and using named pipes to send and receive lists of data between them. With serialization/deserialization mechanism using BinaryFormatter class.

Server:

  static void StartServer()
    {
        var server = new NamedPipeServerStream("PipesEnroll", PipeDirection.InOut);

            while (true)
            {
                StreamReader reader = new StreamReader(server);
                StreamWriter writer = new StreamWriter(server);
                string terminalTemplate;
                string matcherTemplate;
                int mathVersionNumber = 9;
                int numberFingers;
                BinaryFormatter formatterDeserialize = new BinaryFormatter();
                List<byte[]> retrievedList = (List<byte[]>)formatterDeserialize.Deserialize(reader.BaseStream);
                bool isOk = Enroll.EnrollWithoutWCF(retrievedList, mathVersionNumber, out terminalTemplate, out matcherTemplate, out numberFingers);
                List<String> sendList = new List<string>();
                sendList.Add(isOk.ToString());
                sendList.Add(terminalTemplate);
                sendList.Add(matcherTemplate);
                sendList.Add(numberFingers.ToString());
                BinaryFormatter formatterSerialize = new BinaryFormatter();
                formatterSerialize.Serialize(writer.BaseStream, sendList);
                server.Disconnect();
       }

Client:

                    using (var client = new NamedPipeClientStream(".", "PipesEnroll", PipeDirection.InOut))
                        {
                            client.Connect();
                            StreamReader reader = new StreamReader(client);
                            StreamWriter writer = new StreamWriter(client);

                                BinaryFormatter formatterSerialize = new BinaryFormatter();
                                formatterSerialize.Serialize(writer.BaseStream, images);
                                // writer.Write(stream);
                                // writer.Flush();
                                BinaryFormatter formatterDeserialize = new BinaryFormatter();
                                List<String> retrievedList = (List<String>)formatterDeserialize.Deserialize(reader.BaseStream);
                                bool isOK = Convert.ToBoolean(retrievedList[0]);
                                string terminalTemplate = retrievedList[1];
                                string matcherTemplate = retrievedList[2];
                                int numberFingers = Convert.ToInt32(retrievedList[3]);

}

But exception "System.IO.Exception: Pipe is broken" appears on client side when executing formatterSerialize.Serialize(writer.BaseStream, images); in debug mode.

Does anybody have any suggestion on how to avoid this issue?

Andrei Karcheuski
  • 3,116
  • 3
  • 38
  • 39
  • I don't really know off the top of my head what the problem is. And you didn't provide a debuggable example to work with, so there's no way to actually investigate. But I did find another SO example of named pipes where they called WaitForConnection() in the server before they started trying to read from the stream. You might try adding that here. Also, you should just get rid of the StreamReader and StreamWriter objects. You're not using them, and it would be a bad idea to try to mix them with direct reads/writes from/to the underlying streams. – Peter Duniho Oct 21 '14 at 04:12
  • 1
    Add WaitForPipeDrain() before you disconnect. – Hans Passant Oct 21 '14 at 06:12
  • Thank you very much for replies. Indeed, I just forgot WaitForConnection() on server side. – Andrei Karcheuski Oct 21 '14 at 06:23

1 Answers1

1

StreamWriter belongs to NamedPipeClientStream. If NamedPipeClientStream is disposed part of its process is disposing StreamWriter as well. If for any reason StreamWriter is Closed/Disposed in any other part of the code the result will be pipe is broken.

1) Check that formatterSerialize.Serialize is not closing the StreamWriter.

2) Also make sure to flush StreamWriter before exiting Using of NamedPipeClientStream.

  • 1
    Before you answer an old question with no answers yet, you should also check the comments, to see if the solution of the problem is mentioned there and the problem is solved in the meantime. – hotzst Jan 17 '16 at 17:14
  • 5
    I disagree -- a lot. While both suggestions are good and ultimately, the assumption made was correct -- it does not constitute as concise and complete an answer as this one does. Plus, answers do not belong in comments in the first place. – jinzai Jul 18 '16 at 20:19