About the Endpoint Library

Why Endpoints?

All communications share several invariants. At the lowest level, all communications involves reading and writing data. Often, concepts of "connecting" to a counterpart that is "listening" for connections also occur.

This insight is nothing new: Unix's designers built it into the operating system. The same routines you use to manipulate a file in Unix can be used to manipulate a serial or network communications channel. But the Unix method has a number of flaws, mainly that these "overloaded" system calls begin to get rather complicated. Consider the ioctl() call: there are dozens and dozens of flags, switches and modes, and there exist large subsets that only work with specific kinds of connections. This sort of interface is what Steve Maguire calls a "candy machine" interface, because it has dozens of different choices available through a single interface, and the slightest slip when making your choice changes the result dramatically.

C++ to the rescue. In an object-oriented language, you can fix this with language-supported overloading and factored interfaces (classes), rather than a "flat" procedural interface. You can wrap all the behavior that pertains to a given kind of communication up in a clean little object, eliminating the possibility of doing something inappropriate for that kind of channel. For example, a well-written Endpoint wouldn't let you try to connect on a connectionless I/O channel.

Future Directions

Currently, the only Endpoints are for asynchronous and synchronous Winsock 1.1 connections, because I haven't needed anything else. However, I hope to add endpoints for Winsock UDP, System V message queues, BSD sockets, and serial ports on Unix and Win32. For what it's worth, there are Endpoints for Crynwr packet drivers for raw network access under DOS, but this sub-tree hasn't been maintained, and so no longer fits into the class hierarchy properly. Still, if you have a need for these, drop me a line and I'll put them up here.

Contributions of Endpoints are welcome, and I'm not shy about what makes a "legal" Endpoint: serial channels, satellite links, low-level embedded microcontroller busses, whatever. Use your imagination.

I also want to add many more examples to the main distribution. Currently, a single very nice but insufficient example is included: a POP3 server. It's fully functional, and possibly even useful, if you coupled it with an SMTP server. Unfortunately, it only demonstrates server connections, and only the SyncWskEndpoint is used. I have a POP3 client in development that will showcase the AsyncWskEndpoint and the memory and block management classes, but it's not even close to ready yet.

I also want to add a number of smaller examples. I will probably expand the documentation with a tutorial based on these examples.

Also, the DataBlock portion of the library bothers me some. Although I love the interesting semantics of the DataBlocks, it creates some confusion, because it's hard to tell exactly what any given user of DataBlocks really wants, semantics-wise. On the other hand, a lot of Do The Right Thing design work has gone into these classes. Although it is possible to mix DataBlock semantics up so you get memory leaks or double-deletes, great efforts have been made to make sure this is not easy. My current thought on this is to add debugging-only code that uses the typeid operator to test for proper DataBlocks; any thoughts?

Last modified on 6 October 2001 at 06:51 UTC-7 Go to my home page