ivan.web Home | About | Mailing List | Contact


 » Articles










 


Part 1
» 1. Introduction
» 2. Classes
» 3. Creating a Named Pipe
» 4. Connecting Client Pipes
» 5. Writing and Reading Data
» 6. Other Named Pipes Operations
 
Part 2
» 1. Introduction
» 2. Pipe Connections
» 3. ServerNamedPipe Class
» 4. PipeManager Class
» 5. Client Pipe Connections
 
» .NET Named Pipes Discussion

   

Inter-Process Communication in .NET Using Named Pipes, Part 2

3. ServerNamedPipe Class

The Named Pipes server is a multithreaded engine that creates Named Pipes and handles client connections. There are two main classes that provide the server functionality PipeManager and ServerNamedPipe.

The ServerNamedPipe Class wraps a ServerPipeConnection and a separate Thread to keep it alive. Below is the ServerNamedPipe constrictor.

internal ServerNamedPipe(string name, uint outBuffer, 
     uint inBuffer, int maxReadBytes) {
  PipeConnection = new ServerPipeConnection(name, outBuffer, 
     inBuffer, maxReadBytes);
  PipeThread = new Thread(new ThreadStart(PipeListener));
  PipeThread.IsBackground = true;
  PipeThread.Name = "Pipe Thread " + 
     this.PipeConnection.NativeHandle.ToString();
  LastAction = DateTime.Now;
}

The constructor creates a new ServerPipeConnection and starts a new Thread that calls the PipeListener method. The main part of the latter is a loop, which listens to client connections, reads and writes data:

private void PipeListener() {
	CheckIfDisposed();
  try {
    Listen = Form1.PipeManager.Listen;
    Form1.ActivityRef.AppendText("Pipe " + 
       this.PipeConnection.NativeHandle.ToString() + 
       ": new pipe started" + Environment.NewLine);
    while (Listen) {
      LastAction = DateTime.Now;

Read data from the client pipe:

      string request = PipeConnection.Read();
      LastAction = DateTime.Now;
      if (request.Trim() != "") {

The PipeManager.HandleRequest method receives the client request, processes it and returns a response. This response is then written to the pipe:

        PipeConnection.Write(Form1.PipeManager.HandleRequest(request));
        Form1.ActivityRef.AppendText("Pipe " + 
          this.PipeConnection.NativeHandle.ToString() + 
          ": request handled" + Environment.NewLine);
      }
      else {
        PipeConnection.Write("Error: bad request");
      }
      LastAction = DateTime.Now;

Disconnect from the client pipe:

      PipeConnection.Disconnect();
      if (Listen) {
        Form1.ActivityRef.AppendText("Pipe " + 
           this.PipeConnection.NativeHandle.ToString() + 
           ": listening" + Environment.NewLine);

Start listening for a new client connection:

        Connect();
      }
      Form1.PipeManager.WakeUp();
    }
  } 
  catch (System.Threading.ThreadAbortException ex) { }
  catch (System.Threading.ThreadStateException ex) { }
  catch (Exception ex) { 
    // Log exception
  }
  finally {
    this.Close();
  }
}

Note that we do not close the server pipe. Creating a server Named Pipe is a relatively expensive operation so reusing the server pipes improves the performance and reduces the resource consumption on the server.

Our Named Pipes are created in blocking mode therefore the Connect method will block the current thread until a client connection comes through.






.NET Named Pipes Discussion

New Thread | View Details


New Thread | View Details

 
© 2009 by Ivan Latunov. Disclaimer.