The Server Framework was originally harvested
from our work on a project to write a high performance ISO8583 credit card transaction processing server to run on the Windows NT platform. Given the performance requirements we decided to use asynchronous socket I/O
using I/O completion ports
as the basis of our server architecture.
What we discovered was that writing a high performance server that runs on Windows NT and uses sockets to communicate with the outside world isn't that hard once you dig through the API references. What's more most of the code is common between all of the servers that you're likely to want to write. We decided that it should be possible to wrap all of the common code up in some easy to reuse classes. However, when we went looking for some classes to use to write our first prototype socket server all of the examples and articles that we found required the user to pretty much start from scratch or utilise "cut and paste reuse" when they wanted to use the code in their own servers. Also the more complicated examples, ones that actually used I/O completion ports
, tended to stop short of demonstrating real world usage. After all, anyone can write an echo server... So we decided to write our own set of reusable classes that for writing socket servers. Initially the focus was on writing our first production server application for our client, but there was always a focus on reuse as the client had several other server applications in the pipeline and we wanted to be able to use the base communications code in all of them.
One of the key design features of the code is that all I/O operations are executed from a thread that the library has control of. This is, in our view, an essential feature as any outstanding asynchronous I/O requests are terminated when the thread that issued those requests exits (note that this has changed in Windows Vista and we plan to investigate direct dispatch from the calling thread for platforms that support it in a future framework release). Since we wish to ensure that our IO requests are not terminated inappropriately we marshal these calls into an I/O thread pool
rather than issuing them from the calling thread. This adds a little extra work for the library but removes the chance that a user of the library could issue a write call from a thread that they have created and then allow that thread to exit before the write call has completed.
Another important design feature is our attempt to reduce dynamic memory allocation during "normal" operations. See here
for why reducing memory allocations is important. To this end we use allocators that can pool and reuse object instances when allocating sockets
(which are our class wrapper around the bare
and buffers which are the memory that we use for read and write operations.
Since we marshal socket I/O calls into the I/O pool for execution and since all of the I/O calls are asynchronous anyway there's some additional complexity about shutting down a connection cleanly.
The code above looks innocent enough but there's quite a bit of work needed to ensure that the socket remains open long enough for the write that we've issued to complete. We maintain a count of active writes on a socket and if we shut down a connection whilst a write is still in progress we simply make a note of it and perform the actual shut down when the final write has completed.
Our aim when writing the first version of this code back in 2002 was that the code that we wrote for dealing with the low level communication details of I/O completion port
driven asynchronous socket I/O would be reusable and easy to use. That's proven to be the case and we now have many of our own production servers that are based on this code and many clients that have licensed the code for their own uses. As we and our clients have used the code we've extended it in all sorts of directions; supporting OpenSSL
for SSL/TLS, filtering
as well as TCP
as well as IPv4
, multicast, efficient broadcast of data without copying
, and hosting the CLR
. The framework deals with non-paged pool exhaustion
and allows you to protect your server from denial of service
attacks. It's been tested with over 70,000 concurrent connections
and continually refactored and improved.
SocketToolsLicensing "Licensing options" Example clients and servers The latest free version of the code from Len's blog The original articles about the first free release of The Server Framework on CodeProject All the socket server related postings from Len's blog
Bug fix and change notification RSS feed
Contact us by email
for details of more details and for pricing and our standard terms and conditions or to talk to us about custom server development.