Server-Client Communications Using Named Pipes

A server process initiates a connection to a client process by using DosConnectNPipe. Once the pipe has been connected by the server process, the client process must open the pipe by using DosOpen to complete the connection. If no client process has opened the pipe when the server process calls DosConnectNPipe, the function either waits until a client opens the pipe or returns ERROR_PIPE_NOT_CONNECTED, depending on whether the server process created the pipe to wait for data.

Each client process requires a separate instance of a pipe. For example, if a server process creates a named pipe and specifies that four instances of the pipe can be created, the process can then create three more instances of the named pipe (for a total of four pipes, including the original). Each instance has the same name, but each has a unique pipe handle. The process can then connect each pipe to the server. (Each instance must be connected by an explicit use of DosConnectNPipe.) In this example, the server must use each function four times to create and connect four separate instances of the named pipe. Each pipe is then available to a separate client process.

If a client process receives the ERROR_PIPE_BUSY return value from DosOpen, no instances of the given pipe are available. The process can use DosWaitNPipe to wait for an instance to become available. The function waits until an instance is free or until the specified time interval elapses. When an instance becomes free, the process can open the pipe. If several processes are waiting for an instance to become available, the system gives the named pipe to the process that has been waiting the longest.

The server process can disconnect a client process from a pipe by using DosDisConnectNPipe. Ideally, the client process closes the pipe by using DosClose before the server process disconnects the pipe. If the client process has not closed the pipe when the server process disconnects it, the server process forces the pipe closed and the client process subsequently receives errors if it attempts to access the pipe. Note that forcing the closure of the pipe might discard data in the pipe before the client process has had an opportunity to read it.

A process can read and write bytes to a named pipe by using DosRead and DosWrite. A process can read or write messages by using DosTransactNPipe. Depending on the access mode, DosTransactNPipe writes a message to the pipe, reads a message from the pipe, or both. If a named pipe contains unread data or is not a message pipe, DosTransactNPipe fails.

Named pipes created with the NP_ACCESS_INBOUND or NP_ACCESS_OUTBOUND access mode cannot use the DosTransactNPipe function. If the named pipe's client uses the DosTransactNPipe function, the function returns error code 5 (ERROR_ACCESS_DENIED).

If it is reading from the pipe, DosTransactNPipe does not return until a complete message is read, even if the server process specified no-wait mode when the pipe was created.

A process can also read data from a named pipe without removing the data from the pipe by using DosPeekNPipe. This function copies the specified number of bytes from the pipe and returns the number of bytes of data left in the pipe and the number of bytes left in the current message, if any.

DosPeekNPipe also returns the state of the pipe. A named pipe can be in one of the following states:

Named Pipe States

┌───────────────┬─────────────────────────────────────────────┐
│State          │Description                                  │
├───────────────┼─────────────────────────────────────────────┤
│Connected      │The pipe has been created and connected by   │
│               │the server process and has been opened by a  │
│               │client process.  Only connected pipes can be │
│               │written to or read from.                     │
├───────────────┼─────────────────────────────────────────────┤
│Closing        │The pipe has been closed by the client       │
│               │process but has not yet been disconnected by │
│               │the server process.                          │
├───────────────┼─────────────────────────────────────────────┤
│Disconnected   │The pipe has been created by the server      │
│               │process but not connected, or has been       │
│               │explicitly disconnected and not yet          │
│               │reconnected. A disconnected pipe cannot      │
│               │accept a DosOpen request.                    │
├───────────────┼─────────────────────────────────────────────┤
│Listening      │The pipe has been created and connected by   │
│               │the server process but has not yet been      │
│               │opened by a client process. A listening pipe │
│               │is ready to accept a request to open. If the │
│               │pipe is not in a listening state, DosOpen    │
│               │returns ERROR_PIPE_BUSY.                     │
└───────────────┴─────────────────────────────────────────────┘
DosCallNPipe is used to open, write to, read from, and close a named message-format pipe.

Named pipes created with the NP_ACCESS_INBOUND or NP_ACCESS_OUTBOUND access mode cannot use the DosCallNPipe function. If the named pipe's client uses the DosCallNPipe function, the function returns error code 5 (ERROR_ACCESS_DENIED). This function is equivalent to calling DosOpen, DosTransactNPipe, and DosClose If no instances of the pipe are available, DosCallNPipe waits for an instance or returns without opening the pipe if the specified interval of time elapses.

A process can retrieve information about the handle state of a named pipe by using DosQueryNPHState. The handle state is a combination of the instance count, the access mode, and the pipe type (byte or message). DosQueryNPHState also specifies whether the process owning the handle is a server or client and whether the pipe waits if reading and writing cannot proceed.

A process can modify the handle state of a named pipe by using DosSetNPHState. For example, the process can change the reading mode for the pipe, enabling a process to read bytes from the pipe instead of messages.


[Back: Named Pipes]
[Next: Steps in Managing Server-Client Transactions]