System.IO.Exception:管道在客户端损坏

Posted

技术标签:

【中文标题】System.IO.Exception:管道在客户端损坏【英文标题】:System.IO.Exception: Pipe is broken on client side 【发布时间】:2014-10-21 03:34:08 【问题描述】:

我有两个 Windows 应用程序并使用命名管道在它们之间发送和接收数据列表。 具有使用 BinaryFormatter 类的序列化/反序列化机制。

服务器:

  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();
       

客户:

                    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]);

但是执行 formatterSerialize.Serialize(writer.BaseStream, images); 时客户端出现异常“System.IO.Exception: Pipe is broken”处于调试模式。

有人对如何避免这个问题有任何建议吗?

【问题讨论】:

我真的不知道问题出在哪里。而且您没有提供可调试的示例,因此无法进行实际调查。但是我确实找到了另一个命名管道的 SO 示例,他们在开始尝试从流中读取之前在服务器中调用了 WaitForConnection()。您可以尝试在此处添加。此外,您应该摆脱 StreamReader 和 StreamWriter 对象。您没有使用它们,尝试将它们与从/到底层流的直接读取/写入混合是一个坏主意。 在断开连接之前添加 WaitForPipeDrain()。 非常感谢您的回复。确实,我只是忘记了服务器端的 WaitForConnection()。 【参考方案1】:

StreamWriter 属于 NamedPipeClientStream。如果 NamedPipeClientStream 被处置,则其过程的一部分也正在处置 StreamWriter。如果由于任何原因 StreamWriter 在代码的任何其他部分中关闭/处置,则结果将是管道损坏。

1) 检查 formatterSerialize.Serialize 没有关闭 StreamWriter。

2) 还要确保在退出使用 NamedPipeClientStream 之前刷新 StreamWriter。

【讨论】:

在回答一个还没有答案的老问题之前,您还应该检查一下 cmets,看看那里是否提到了问题的解决方案,同时问题也得到了解决。 我不同意——很多。虽然这两个建议都是好的,而且最终,所做的假设是正确的——它并不像这个一样简洁和完整的答案。另外,答案首先不属于 cmets。

以上是关于System.IO.Exception:管道在客户端损坏的主要内容,如果未能解决你的问题,请参考以下文章

客户端断开连接后如何使命名管道不忙?

客户端检查命名管道主机是不是打开

命名管道:服务器端如何知道客户端已断开连接?

命名管道如何识别客户端

如何在 CI 管道中存储多个客户端的机密文件?

UWP C# 管道客户端无法连接到 Win32 C++ 管道服务器