Search code examples
c#pipenamedpipeserverstream

Way to check if NamedPipeServerStream started in Client side


I have a client using NamedPipeClientStream and a server using NamedPipeServerStream.

The client may start before the server, and when it call clientStream.Connect(timeout) i get TimeoutException as expected.

Is there any way I can check if there is a NamedPipeServerStream listening before calling the Connect to prevent an exception?


Solution

  • I suggest you should use an EventWaitHandle. On all clients, call WaitOne () and on server after opening the stream, call 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).

    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.

    3) User rights problems

    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.

    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. 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).