检查NamedPipeServerStream是否在客户端启动的方法

本文关键字:启动 方法 客户端 NamedPipeServerStream 是否 检查 | 更新日期: 2023-09-27 18:06:40

我有一个客户端使用NamedPipeClientStream和一个服务器使用NamedPipeServerStream。

客户端可能在服务器之前启动,当它调用clientStream.Connect(timeout)时,会得到预期的TimeoutException。

是否有任何方法我可以检查是否有一个NamedPipeServerStream监听之前调用连接,以防止异常?

检查NamedPipeServerStream是否在客户端启动的方法

如果五年后有人遇到这个问题,这可能会有所帮助:

var isPipeRunning = Directory.GetFiles( @"''.'pipe'" ).Contains( $"''.'pipe'{pipeName}" )

我建议你应该使用EventWaitHandle。在所有客户机上调用WaitOne(),在打开流后在服务器上调用Set()。

所以,在"服务器"端,这样写:

EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.ManualReset, String.Format(@"Global'{0}", "SERVER_OPENED_HANDLE"));
OpenStream (); // inside this method you would have code that opens your named pipe for incomming messages
// finally, signal that you are done
handle.Set ();

在客户端,这样写:

EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.ManualReset, String.Format(@"Global'{0}", "SERVER_OPENED_HANDLE"));
// here your thread will sleep until the server calls "Set"
handle.WaitOne ();
// then you can safelly connect to the server here
ConnectToServer ();

只剩下几种情况需要处理:

1)在服务器上无法打开管道,因为已经有一个打开的同名管道(将抛出异常)。

2)你成功打开了管道,你通知客户端你已经准备好了,但在那之后,一毫秒后,服务器由于一些意想不到的原因崩溃,客户端无法到达服务器。

3)用户权限问题

在所有这些情况下,你应该使用try/catch来处理这些异常,通常情况下,如果一切顺利,这段代码将确保客户端在服务器成功打开管道之前不会尝试连接。

无论如何,我建议使用更先进的技术来通过命名管道制作IPC,例如使用WCF或甚至。net Remoting,除了它被许多人(不包括我)认为过时的事实之外,至少对于IPC通信来说是非常体面的。这将给你自由和可扩展性(也许有一天你需要你的客户端能够驻留在其他机器上,你将不得不从IPC切换到LAN通信,甚至在WAN/internet)。

仅使用NamedPipeClientStream是无法检查这一点的。但是,您可以使用如下的Mutex

// In the server
var mutex = new System.Threading.Mutex(false, "MyPipeMutex");
OpenPipeAndRunServer();
mutex.Close();
// In the client process    
var mutex = new System.Threading.Mutex(false, "MyPipeMutex");
if (!mutex.WaitOne(0, false))
{
    OpenPipe();
}
mutex.Close();

你可能想在try-finally块中包装Close调用,以确保它总是关闭。在客户端中,您可以使用不同的超时来实际等待NamedPipe被打开。

你也可以捕获异常作为变通。