This example continues the theme that was started with the UDP Pseudo Connection Server
example and builds a UDP server that builds a slightly more complex 'virtual connection' over a stream of UDP datagrams from the same client. The basic structure of this server is similar to the UDP Pseudo Connection 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 UDP Pseudo Connection 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.
This version of the server takes a slightly different approach and creates a new socket for each new connection. This results in datagrams flowing from the client to the server's "well known port" to establish a new connection and from then on between the client and a port on the server that has been allocated for the sole use of the connection. This can cause problems with some NAT firewalls as the client sends to one port and the server replies from another. The advantage on the server is that the demultiplexing of the inbound connection data is done by Winsock rather than by user code and each connection has its own recv buffer space, so potentially ensuring that fewer datagrams are discarded by the network layer when the server is busy.
The structure of the code is slighly different to the previous UDP servers as this example uses a server
to manage datagrams that are directed to the server's "well known port" and a connection manager to deal with the connections once they have been established. This requires two different socket allocators and generally increases the complexity of ServerMain.cpp.
The server itself is much simpler as all it now deals with are connection establishment datagrams on the "well known port". All of the work is done in the connection manager. The connection manager deals with accepting new connections, creating an entry in the connection collection for them and creating a new socket to deal with the connection. The connection manager first does a lookup for the new client address and port as this helps in situations where a connection establishment datagram from a client address/port is sent to the "well known port" more than once; the connection manager finds the existing connection and routes the new request to it. Once a connection is established we can store the per connection data as socket data since the new socket will be persistent for the duration of the "connection" and we send the response data back on the new connection.
A diagram may help.
The client connects to the server's well known port.
Client 192.168.0.1 - port 12121 ------------------------> Server 192.168.0.2 - port 5050
The server allocates a new socket for the connection and sends the response back
Client 192.168.0.1 - port 12121 <------------------------ Server 192.168.0.2 - port 23232
The client switches to using the new server port for the duration of this connection.
Client 192.168.0.1 - port 12121 -------------------------> Server 192.168.0.2 - port 23232
Note that this design can cause problems with NAT firewalls and we address that issue somewhat with the next server design.