命名管道服务器和客户端 - 没有消息

4

我正在尝试学习如何使用命名管道。因此,我在LinqPad中创建了一个服务器和客户端。

以下是我的服务器代码:

var p = new NamedPipeServerStream("test3", PipeDirection.Out);
p.WaitForConnection();
Console.WriteLine("Connected!");
new StreamWriter(p).WriteLine("Hello!");
p.Flush();
p.WaitForPipeDrain();
p.Close();

这是我的客户端:
var p = new NamedPipeClientStream(".", "test3", PipeDirection.In);
p.Connect();
var s = new StreamReader(p).ReadLine();
Console.Write("Message: " + s);
p.Close();

我运行了服务器和客户端,服务器上显示"已连接!",说明连接成功。但是,客户端始终只显示 Message:,后面没有任何内容,因此实际上并没有从服务器到客户端传输数据以便显示。我已经尝试交换管道方向,并让客户端发送数据到服务器,但结果相同。 在这个例子中,为什么数据没有被打印到屏幕上?我漏掉了什么吗? 谢谢!

根据StreamReader.ReadLine文档,如果到达流的末尾,它将返回null。也许在您执行ReadLine时,管道中没有数据,流是空的。如果s为null,您可能需要循环回来再次尝试读取。 - user957902
2个回答

3

就像L.B说的一样,你必须清除StreamWriter。但采用using模式将防止这种错误:

using (var p = new NamedPipeServerStream("test3", PipeDirection.Out))
{
    p.WaitForConnection(); 
    Console.WriteLine("Connected!"); 
    using (var writer = new StreamWriter(p))
    {
         writer.WriteLine("Hello!");
         writer.Flush();
    }
    p.WaitForPipeDrain(); 
    p.Close();
}

在上面的代码中,即使省略了Flush()Close(),一切也会按预期工作(因为这些操作在对象被处理时也会执行)。此外,如果抛出任何异常,所有内容仍将正确清除。

看起来 p.WaitForPipeDrain(); 应该放在上一行:使用 StreamWriter 的代码块中。否则,使用代码块会关闭管道,并导致 System.ObjectDisposedException 错误消息=无法访问已关闭的管道。 - jing

2

请按照以下方式更改您的服务器代码:

StreamWriter wr = new StreamWriter(p);
wr.WriteLine("Hello!\n");
wr.Flush();

您的字符串在StreamWriter中没有被刷新


是的,您需要在最高级别上刷新(通常应避免在关闭流之前不先关闭该流的所有用户)。但我认为额外的 \n 不是必需的。 - Allon Guralnek
哇,就是这样!非常感谢你!! - mellamokb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接