简体   繁体   English

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

[英]Way to check if NamedPipeServerStream started in Client side

I have a client using NamedPipeClientStream and a server using NamedPipeServerStream.我有一个使用 NamedPipeClientStream 的客户端和一个使用 NamedPipeServerStream 的服务器。

The client may start before the server, and when it call clientStream.Connect(timeout) i get TimeoutException as expected.客户端可能在服务器之前启动,当它调用 clientStream.Connect(timeout) 时,我按预期得到 TimeoutException。

Is there any way I can check if there is a NamedPipeServerStream listening before calling the Connect to prevent an exception?有什么方法可以在调用 Connect 之前检查是否有 NamedPipeServerStream 侦听以防止异常?

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

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

I suggest you should use an EventWaitHandle.我建议您应该使用 EventWaitHandle。 On all clients, call WaitOne () and on server after opening the stream, call Set ().在所有客户端上调用WaitOne(),在服务器端打开流后调用Set()。

So, on "server" side, write this:所以,在“服务器”端,这样写:

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 ();

On client side, write something like this:在客户端,写这样的东西:

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 ();

There remains just a few situations to handle:剩下的只有几种情况需要处理:

1) The pipe can't be opened on server becase there is already an opened pipe with the same name (will throw an exception). 1) 无法在服务器上打开管道,因为已经有一个同名打开的管道(将引发异常)。

2) You successfully opened the pipe, you notified clients that you are ready but after that, a milisecond after, the server crushes from some unexpected reason and the client cannot reach the server. 2)您成功打开管道,您通知客户端您已准备就绪,但在那之后,一毫秒后,服务器因某种意外原因崩溃,客户端无法访问服务器。

3) User rights problems 3)用户权限问题

In all these situations, you should handle these exceptions using a try / catch and normally, if all goes well, this code will ensure that the client will NOT try to connect before the server successfully opened the pipe.在所有这些情况下,您应该使用 try / catch 处理这些异常,并且通常情况下,如果一切顺利,此代码将确保客户端不会在服务器成功打开管道之前尝试连接。

Anyway, I suggest using a more advanced technique for making IPC through Named Pipes such as using WCF or even .NET Remoting wich besides the fact that it's somehow considered obsolete by many (don't include me) is very decent at least for IPC communication.无论如何,我建议使用更先进的技术来通过命名管道制作 IPC,例如使用 WCF 甚至 .NET Remoting,除了事实上它在某种程度上被许多人(不包括我)认为已经过时,至少对于 IPC 通信来说是非常不错的. This will give you the freedom and scalability (maybe one day you will need your clients to be able to reside on other machines, and you will have to switch from IPC to a LAN communication or even in WAN / internet).这将为您提供自由和可扩展性(也许有一天您需要您的客户端能够驻留在其他机器上,并且您将不得不从 IPC 切换到 LAN 通信,甚至在 WAN / Internet 中)。

There is no way to check this only using a NamedPipeClientStream .仅使用NamedPipeClientStream无法检查这一点。 However, you can use a Mutex like so但是,您可以像这样使用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();

You will probably want to wrap the Close calls in a try-finally block to make sure it always closes.您可能希望将Close调用包装在 try-finally 块中,以确保它始终关闭。 In the client you can use a different timeout to actually wait for the NamedPipe to be opened.在客户端中,您可以使用不同的超时来实际等待 NamedPipe 打开。

You can also catch the exception as a work around.您还可以捕获异常作为解决方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM