New UDP Server examples

The new release of the licensed, high performance, I/O completion port, server framework includes lots of new example clients and servers; the framework now comes with 74 fully working example that showcase various aspects of the framework.

Since the UDP side of the framework has undergone a lot of work recently to support filtering and in preparation for the release of several reliable UDP protocols there are lots of new UDP server examples.

There are, of course, the examples that have always shipped with the framework, though with this release they’ve been moved out of the “Simple Servers” example set and into the new “UDP servers” example set. These are as follows:

The examples above deal with UDP servers that work in terms of individual datagrams. It’s often common to build a connection oriented system such that a stream of datagrams from a single client might represent a continuous conversation rather than a sequence of isolated datagrams. Whilst there may be issues around ‘connection oriented UDP streams’ with regards to reliable NAT traversal and firewalls these aren’t addressed in the following examples which will reliably work on direct connections between a client and a server on the same network segment and may work elsewhere.

  • UDPPseudoConnectionServer - A UDP server that uses the client’s address and port to separate datagrams into ‘connection oriented UDP streams’ and uses a per stream read timer to determine when a connection has ended.

  • UDPPseudoConnectionServerTest - A client for the above server which can initiate multiple concurrent UDP streams.

  • UDPPseudoConnectionServer2 - A UDP server that uses an explicit ‘connection id’ within each datagram to separate datagrams into ‘connection oriented UDP streams’ and uses a per stream read timer to determine when a connection has ended. Note that this server is slightly more performant than the previous one as it can use a Single Writer, Multiple Reader, lock rather than the mutual exclusion lock that the previous server uses to manage its connection collection.

  • UDPPseudoConnectionServerTest2 - A client for the above server which can initiate multiple concurrent UDP streams.

The examples above are all structured in such a way that the server receives all datagrams on a single well known port and demultiplexes them based on either address or connection id. The following examples take a slightly different approach which is to bind a new socket for each new connection so that each connection sends data to its own server socket. This makes for a more efficient server as the demultiplexing is done in the kernel and each connection has its own socket recv buffer, but it is potentially more complex from a NAT traversal point of view.

  • UDPConnectionServer - A UDP server that uses the client’s address and port to separate datagrams into ‘connection oriented UDP streams’ and uses a per stream read timer to determine when a connection has ended. When a new connection is detected a new socket id created on the server and the response from the new connection is sent on the new socket; the client is expected to detect this and switch to the new port and use that for all future datagrams on that logical connection.

  • UDPConnectionServerTest - A client for the above server which can initiate multiple concurrent UDP streams and correctly detects the implicit port change.

  • UDPConnectionServer2 - A UDP server similar to the one above that uses an explicit ‘change port’ response message which contains details of the connection’s new port. The client can then instigate the switch to the new server port - this works if the client is behind certain kinds of NAT where the client and server above will fail.

  • UDPConnectionServerTest2 - A client for the above server which responds to the port switch message to continue the connection on the new port.

As examples of the new datagram filtering functionality there are several UDP servers that demonstrate how filters can be used. First a group of servers that demonstrate stateless filtering with a compression filter. The compression filter uses ZLib to compress the content of datagrams being sent between client and server. These examples are part of the “Compressing Servers” example set.

  • CompressingEchoServerUDP - shows how easy it is to layer functionality onto a datagram server now that they support the filtering API.

  • CompressingEchoServerTest - Likewise, adding compression to a client is equally simple.

  • CompressingUDPPseudoConnectionServer2 - Servers with explicit connection id’s that are required for routing need the compressed part of the datagram to start after the connection id so that the connection id can be used before the datagram is uncompressed. The compression filter makes this easy by allowing a user defined number of bytes at the start of the datagram to be uncompressed.

  • CompressingUDPConnectionServer - A UDP server that uses the client’s address and port to separate datagrams into ‘connection oriented UDP streams’ with compression.

  • CompressingUDPConnectionServer2 - A UDP server similar to the one above that uses an explicit ‘change port’ response message which contains details of the connection’s new port.

As an example of a stateful datagram filter there are several UDP servers that demonstrate running a “Carmack Unreliable Delta system” see here as over UDP ‘connections’. These are in the “Unreliable Delta Servers” example set.

  • UnreliableDeltaUDPPseudoConnectionServer - shows how you need to manage stateful filtering manually when you’re using a “pseudo connection” where all datagrams for all connections flow through the same “well known port” on the server.

  • UnreliableDeltaUDPPseudoConnectionServer2 - shows how we can include some of our own header bytes into the unreliable delta messages so that we can extract our explicit connection id before processing the unreliable delta message.

  • UnreliableDeltaUDPConnectionServer - shows how much easier this all is when you have a socket per “connection” and you can just use a filter to do all of the hard work for you.

Of course all of the examples come with corresponding clients so that you can test them.