C# 命名管道,如何检测客户端断开连接
本文关键字:检测 客户端 连接 断开 何检测 管道 | 更新日期: 2023-09-27 18:30:58
我当前的命名管道实现如下所示:
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
}
如何正确检测客户端何时断开连接?
设置读取超时并在发生超时时轮询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,我认为您仍然需要手动关闭它,但它确实可以让您检测何时出现问题。
在写入管道后使用WaitForPipeDrain()
方法(使用 WriteByte()
或 Write()
)并捕获异常"管道已损坏"。
您可能希望将其放在while
循环中,并继续写入管道。
在同步调用的情况下,你跟踪 Stream 抽象类的 ReadByte 的 -1 返回,该返回由 NamedPipeServerStream 继承:
var _pipeServer = new NamedPipeServerStream(PipeConst._PIPE_NAME, PipeDirection.InOut);
int firstByte = _pipeServer.ReadByte();
const int END_OF_STREAM = -1;
if (firstByte == END_OF_STREAM)
{
return null;
}
文档确实指出:
//
// Summary:
// Reads a byte from a pipe.
//
// Returns:
// The byte, cast to System.Int32, or -1 indicates the end of the stream (the pipe
// has been closed).
public override int ReadByte();
只有在第一次读取失败后,您的 IsConnected 属性才会正确设置为 false:
_pipeServer.IsConnected
您可能会观察到,即使在Microsoft的官方插图(更准确地说是在 StreamString 类中)未执行此检查:
不要忘记投票支持这个答案并访问我的 Youtube 频道。有关我的个人资料的更多信息。
问候!