Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows named pipes in practice

With Windows named pipes, what is the proper way to use the CreateNamedPipe, ConnectNamedPipe, DisconnectNamedPipe, and CloseHandle calls?

I am making a server app which is connecting to a client app which connects and disconnects to the pipe multiple times across a session.

When my writes fail because the client disconnected, should I call DisconnectNamedPipe, CloseHandle, or nothing on my handle.

Then, to accept a new connection, should I call CreateNamedPipe and then ConnectNamedPipe, or just ConnectNamedPipe?

I would very much like an explanation of the different states my pipe can be in as a result of these calls, because I have not found this elsewhere.

Additional info:

Language: Python using the win32pipe,win32file and win32api libraries.

Pipe settings: WAIT, no overlap, bytestream.

like image 670
oyvind Avatar asked Aug 06 '13 10:08

oyvind


2 Answers

It is good practice to call DisconnectNamedPipe then CloseHandle, although CloseHandle should clean everything up.

The MSDN documentation is a little vague and their server example is pretty basic. As to whether you reuse pipe handles, it seems that it is your own choice. Documentation for DisconnectNamedPipe seems to indicate that you can re-use a pipe handle for a new client by calling ConnectNamedPipe again on that handle after disconnecting. The role of ConnectNamedPipe seems to be to assign a connecting client to a handle.

Make sure you are cleaning up pipes though as MSDN states the following

Every time a named pipe is created, the system creates the inbound and/or outbound buffers using nonpaged pool, which is the physical memory used by the kernel. The number of pipe instances (as well as objects such as threads and processes) that you can create is limited by the available nonpaged pool. Each read or write request requires space in the buffer for the read or write data, plus additional space for the internal data structures.

I'd also bare the above in mind if you are creating/destroying a lot of pipes. My guess that it would be better to operate a pool of pipe handles if there are many clients and have some grow/shrink mechanism to the pool.

like image 141
djgandy Avatar answered Oct 04 '22 20:10

djgandy


I have managed to achieve what I wanted. I call CreateNamedPipe and CloseHandle exactly once per session, and I call DisconnectNamedPipe when my write fails, followed by another ConnectNamedPipe.

The trick is to only call DisconnectNamedPipe when the pipe was actually connected. I called it every time I tried to connect "just to be sure" and it gave me strange errors.

See also djgandy's answer for more information about pipes.

like image 42
oyvind Avatar answered Oct 04 '22 19:10

oyvind