![]() |
Modules | |
Stream Sockets | |
Datagram Sockets | |
Addresses | |
A quick look at the inheritance diagram for IAddress shows that there's more to modelling a socket address than might, at first, meet the eye. The concrete classes CAddressIPv4 and CAddressIPv6 are all that you're likely to use on a day to day basis but within a server or client you may come across instances of IAddress being passed around. The reason being that most of the code is completely address agnostic and the addresses reported to you from a server or client can handle any address format that is supported by Winsock. CAddress is a simple smart pointer around the actual class that does all of the work, CAddressImpl. | |
Sockets utility code | |
Socket allocators | |
To help reduce the amount of memory allocation and deallocation that goes on through the life of a client or server we use allocators that pool their allocations and reuse them. This means that once a server is running with a fairly stable maximum number of connections no memory allocation needs to be done on each new connection. The structure of a socket allocator is fairly complex, possibly unecessarilly so. There are currently three different types of allocators, one for each of the socket types supported. Most of the code for these allocators is common and exists in the CSocketAllocator class. There is then a TSocketAllocator template and several interfaces (one for each socket type) and finally a concrete allocation class for each socket type. I'm pretty sure that this class structure could be collapsed a bit by a slighly more aggressive use of templates. | |
Sockets | |
Given that we support two basic kinds of socket, stream and datagram you would be forgiven for expecting us to have two types of socket. In fact there are four. The reason for the existence of the third is that we differentiate between pure datagram servers (i.e. a server where the sockets can only communicate back with the address that sent the datagram in the first place) and more general purpose datagram connection managers with sockets that can be used to Read() and RecvFrom() any address. The reason for the fourth is that sometimes it is useful to have a TCP stream where the socket helps to maintain the order of the data buffers flowing through the framework and sometimes this additional book-keeping is just pointless overhead. | |
Socket servers | |
Socket servers are how you build servers using The Server Framework. | |
Connection managers | |
Connection managers are how you build clients using The Server Framework. | |
Callback events | |
Connection managers, socket servers and sockets communicate with code that uses the library via callback interfaces. As a user of the library you implement these interfaces to handle events that occur on a socket during its life-cycle. There are default implementations of the key callback interfaces which act as null objects and provide a safe, "do nothing" implementation of the interface so that you can simply derive from them an implement just the methods that you're actually interested in. For a simple TCP server this may be as little as two methods from the IStreamSocketServerCallback interface; IStreamSocketServerCallback::OnConnectionEstablished() and IStreamSocketServerCallback::OnReadCompleted() | |
Filtering | |
It's possible to install filters into the data stream of a stream based socket connection or a DatagramSockets "datagram socket" so that the data can be manipulated on the way into and out of the client or server without the business logic of the system needing to know or care that the data is being filtered. This is useful for adding security, such as SSL, or compression to a data stream without needing to change the business logic code in any way. | |
Sequencing |