In two previous articles I have shown how to use anonymous pipes to transfer a byte stream or an object between two processes. Anonymous pipes are limited to processes which are running on the same PC. This limitation will removed by named pipes which I want to explain within this article.
Named pipes
In summary named pipes have the following features:
- Communication between one server and one or several clients
- One-way or two-way communication
- Supports data transfer between local processes and between different machines on a network
- Full-duplex communication
- Message based communication
- Client identity change to use the client identity on the connected pipe server
- Byte-stream oriented
The pipe is implemented in a first-in-first-out manner. The sender will write data to the pipe and the receiver may read it. The data is passed to the reader in the same order in which it was written. The pipe may be used to read and write data. Therefore, in contrast to anonymous pipes, it is sufficient to create one pipe for a two-way communication.
Server process
The following source code shows a console application which implements a named pipe to send and receive data. The server waits until the client is connected. Afterwards data in form of byte data is send to the client and response data is received.
static void Main(string[] args) { //create pipe var pipe = new NamedPipeServerStream("MyPipe", PipeDirection.InOut, 1); //wait until client connects pipe.WaitForConnection(); Console.WriteLine("Client is connected"); //write and read data try { //write data byte dataSend = 48; pipe.WriteByte(dataSend); Console.WriteLine("Parent send: " + dataSend.ToString()); //read data int dataReceive = pipe.ReadByte(); Console.WriteLine("Parent receive: " + dataReceive.ToString()); } //catch exception on broken or disconnected pipe catch (IOException exception) { Console.WriteLine("Error: {0}", exception.Message); } //close pipe pipe.Close(); Console.ReadKey(); }
Child process
Within the child process, in this example implemented as console application, also a pipe is created. By setting the according address and pipe name of the server process it is possible to connect to the pipe and receive the byte, send by the parent, and send some other byte back.
static void Main(string[] args) { //connect var pipe = new NamedPipeClientStream("127.0.0.1", "MyPipe", PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Impersonation); pipe.Connect(); Console.WriteLine("Connected with server"); //read data int dataReceive = pipe.ReadByte(); Console.WriteLine("Client receive: " + dataReceive.ToString()); //write data byte dataSend = 24; pipe.WriteByte(dataSend); Console.WriteLine("Client send: " + dataSend.ToString()); //close pipe pipe.Close(); Console.ReadKey(); }
Summary
Named pipes offer an easy way to transfer data between several processes on different network machines. Within this example only byte data was used. In the next article of this series I want to show you how you may transfer complex data classes by using serialization
Pingback: Inter-Process Communication with named pipes, Part 02: transfer an object | coders corner