The Plumbing library provides C++ wrapper facades for Berkeley sockets. It is intended for single-threaded applications.
* The plumbing::endpoint class hierarchy represents things that typically have a file descriptor. This interface defines methods for reading data when select(2) says it is available for reading, writing data when select(2) says it is available for writing, and the necessary ancilliary method to make it happen.
* The plumbing::endpoint_listener hierarchy are classes that listen for a connection, and call a factory method (that derived classes must implement) when a connection is accepted. These manufactured endpoints are then also managed by the main loop, all in a single thread.
* The plumbing::reactor class is used to represent the main loop of your program. It monitors endpoints and calls the appropriate methods for each activity. When there is no activity, it uses no CPU, and blocks in the select(2) system call.
* It is possible to write network clients using only a plumbing::reactor instance, and one or more plumbing::endpoint derived classes instances. Clients can connect to more than one server simultaneously.
* It is possible to write network daemons using only a plumbing::reactor instance, and one or more plumbing::endpoint_listener derived classes, that in turn create one or more server plumbing::endpoint derived classes instances.
* It is possible to write programs that are both clients and servers, all managed with a single plumbing::reactor instance.
There are several example programs in the sources:
* The plumbing-inet-reactor(1) command implements a TCP-only equivalent of the traditional inetd(8) super-server. It is also able to service daytime (port 13) connections internally, and some other standard services as well, with only a single thread. (See the plumbing-inet-reactor/main.cc file.)