2009-05-21 307 views
16

我有两个通过命名管道相互通信的.NET应用程序。第一次通过时一切都很好,但在发送第一条消息并且服务器要再次收听之后,WaitForConnection()方法会抛出System.IO.Exception,并显示消息管道已损坏。
为什么我在这里得到这个异常?这是我第一次使用管道工作,但是类似的模式在过去也适用于我的套接字。System.IO.Exception:管道中断

代码ahoy!
服务器:

using System.IO.Pipes; 

static void main() 
{ 
    var pipe = new NamedPipeServerStream("pipename", PipeDirection.In); 
    while (true) 
    { 
     pipe.Listen(); 
     string str = new StreamReader(pipe).ReadToEnd(); 
     Console.Write("{0}", str); 
    } 
} 

客户:

public void sendDownPipe(string str) 
{ 
    using (var pipe = new NamedPipeClientStream(".", "pipename", PipeDirection.Out)) 
    { 
     using (var stream = new StreamWriter(pipe)) 
     { 
      stream.Write(str); 
     } 
    } 
} 

到sendDownPipe第一次调用获取服务器打印我送就好了消息,但是当它循环回到再听一遍,它poops。

+0

我认为你有这个问题的原因是因为该行的“新的StreamReader(管)”。创建的流读取器的范围是第一个while循环,然后重新创建。然而,流读取器的行为是关闭它们正在包装的流 - 因此一旦它超出范围,它将关闭管道流。你可以尝试将它的声明移出while循环并检查(P.S:如果你这么做的话,我没有亲自尝试代码的工作 - 只是想添加一个评论而不是回答) – user3141326 2016-04-07 15:05:43

回答

16

我会发布我的代码,似乎工作 - 我很好奇,因为我从来没有做过任何与管道。我没有在相关命名空间中找到您为服务器端命名的类,因此这里是基于NamedPipeServerStream的代码。回调的东西只是因为我不能被两个项目困扰。

NamedPipeServerStream s = new NamedPipeServerStream("p", PipeDirection.In); 
Action<NamedPipeServerStream> a = callBack; 
a.BeginInvoke(s, ar => { }, null); 
... 
private void callBack(NamedPipeServerStream pipe) 
{ 
    while (true) 
    { 
    pipe.WaitForConnection(); 
    StreamReader sr = new StreamReader(pipe); 
    Console.WriteLine(sr.ReadToEnd()); 
    pipe.Disconnect(); 
    } 
} 

,客户机将这样的:

using (var pipe = new NamedPipeClientStream(".", "p", PipeDirection.Out)) 
using (var stream = new StreamWriter(pipe)) 
{ 
    pipe.Connect(); 
    stream.Write("Hello"); 
} 

我可以与服务器运行,没有概率多次重复以上块。

+0

这样做。我猜想,当客户脱离另一端时,他们不会有明显的脱节。谢谢。 – 2009-05-22 14:06:03

5

当我从客户端断开连接后,从服务器调用pipe.WaitForConnection()时,发生了问题。该解决方案是再次赶上IOException异常和调用pipe.Disconnect(),然后调用pipe.WaitForConnection():

while (true) 
{ 
    try 
    { 
     _pipeServer.WaitForConnection(); 
     break; 
    } 
    catch (IOException) 
    { 
     _pipeServer.Disconnect(); 
     continue; 
    }    
}