C#命名管道,如何检测客户端断开连接

Posted

技术标签:

【中文标题】C#命名管道,如何检测客户端断开连接【英文标题】:C# Named Pipes, how to detect a client disconnecting 【发布时间】:2013-09-12 08:24:32 【问题描述】:

我当前的命名管道实现如下所示:

while (true)

  byte[] data = new byte[256];                        
  int amount = pipe.Read(data, 0, data.Length);
  if (amount <= 0)
  
      // i was expecting it to go here when a client disconnects but it doesnt
     break;
  
  // do relevant stuff with the data

如何正确检测客户端何时断开连接?

【问题讨论】:

【参考方案1】:

设置读取超时并在发生超时时轮询NamedPipeClientStream.IsConnected 标志。

读取超时将导致在超时时间内空闲的读取抛出InvalidOperationException

如果您没有阅读,并且想要检测断开连接,请在工作线程上调用此方法,以在管道连接的整个生命周期内。

while(pipe.IsConnected && !isPipeStopped) //use a flag so that you can manually stop this thread

    System.Threading.Thread.Current.Sleep(500);


if(!pipe.IsConnected)

    //pipe disconnected
    NotifyOfDisconnect();

【讨论】:

谢谢,但如果我故意不从管道读取超过此超时的持续时间怎么办?我的管道大部分时间都是空闲的。 我建议在管道的整个生命周期内轮询 IsConnected 的工作线程。也许将其全部包含在一个专门的课程中。更新答案【参考方案2】:

判断管道是否已损坏(远程)的一种简单方法是始终使用异步读取而不是同步读取,并且始终至少异步提交一次读取。也就是说,对于您获得的每次成功读取,发布另一个异步读取,无论您是否打算读取另一个。如果您关闭管道,或者远程端关闭它,您将看到异步读取完成,但读取大小为空。您可以使用它来检测管道断开连接。不幸的是,管道仍然会显示 IsConnected,我认为您仍然需要手动关闭它,但它确实允许您检测何时出现问题。

【讨论】:

我不会使用计时器。【参考方案3】:

写入管道后使用WaitForPipeDrain() 方法(使用WriteByte()Write())并捕获异常“管道已损坏”。

您可能希望将其放入 while 循环并继续写入管道。

【讨论】:

以上是关于C#命名管道,如何检测客户端断开连接的主要内容,如果未能解决你的问题,请参考以下文章

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

在断开连接之前等待读取命名管道

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

当客户端除了快速连接-断开之外啥都不做时,命名管道会失败

如何使用重叠 I/O 检测到命名管道服务器的客户端连接?

如何在WebSocket的服务器侧检测客户端的断开连接