This example shows you how to build another simple server. The basic structure is very similar to the Basic Echo Server
example and you should go and read about that first and have a good understanding of how everything fits together. This document will only cover the differences between the Basic Echo Server
example and this example.
This example is shipped with all licensed versions of The Server Framework and it requires the core server framework libraries (see here
for licensing options). You can always download the latest version of this example from here
; and although you will need the correct libraries to be able to build it you can look at the example code and see how it works and perhaps get ideas from it. A compiled, unicode release, build of this example is available on request if you require it for performance analysis of the framework.
The main difference between this server and the Basic Echo Server
is that this server used AcceptEx()
to accept new socket connections. This means that the only significant code change between the two examples is that this example derives from JetByteTools::Socket::CStreamSocketServerEx
rather than from JetByteTools::Socket::CStreamSocketServer
The implications of this change are that the server uses one less thread to do its work. JetByteTools::Socket::CStreamSocketServer
has a thread that runs to manage accepting new connections. Each time there's a new connection established this thread wakes up (when accept() returns) and does some work. It then calls accept() again and goes back to sleep.
This server, derived from JetByteTools::Socket::CStreamSocketServerEx
, doesn't do any of that. It posts some overlapped AcceptEx() requests when the server starts accepting connections but it does this from the thread that calls
. It then posts more overlapped AcceptEx() calls from whichever I/O thread is handling the completion of an AcceptEx() call. So, as existing calls complete and new connections are established new potential connections are queued up. This is considerably more efficient as there's one less thread to be scheduled and one less thread to contend for server resources (such as buffer or socket allocators). It also allows for servers that scale better; in servers that listen on multiple ports there's an extra thread per port if the server is based on JetByteTools::Socket::CStreamSocketServer
rather than JetByteTools::Socket::CStreamSocketServerEx
So, why do we support the other way if it's less efficient? AcceptEx() is a microsoft extension function for Winsock as such you may be writing code on a platform where it's not supported. It's unlikely, but possible. Although most of the example servers use JetByteTools::Socket::CStreamSocketServer
this is historical. Consider using JetByteTools::Socket::CStreamSocketServerEx
unless you can come up with a valid reason not to!
Note that at this time JetByteTools::Socket::CStreamSocketServerEx
does not support accepting a new connection and reading data from that connection at the same time. This is planned for a future release but at present we have no customers who actually really need this functionality and protecting against denial of service attacks on that kind of architecture is 'non-trivial' without adding a watch-dog thread to the system.