Challenge #1: SimpleServer API

This week I’ve prepared a little challenge in C++ programming. The example is not extrodinarily complex, but not completely simple either. The purpose of this example is, to challenge myself a little to get to know boost::asio networking, and to contemplate about how simple APIs for prototyping could look.

So the challenge is to create a class, that allows prototyping simple network servers, by implementing a convenient base class. The interfaces and base classes are already layed out, including an example that send the reply “Hello” for any incoming connection.

The specification is a bit open, and is not so much concerned with corner cases. So using the simplest solution possible is probably the right thing to do.

Ok, here we go for the boilerplate: read on, I will add a few explanations below.

#include <string>
#include <functional>
#include <iostream>

class IConnection
{
public:
    typedef std::function<void(const std::string& str)> send_function;
    virtual void receive(const std::string& str) = 0;
    virtual ~IConnection() {}
    IConnection(send_function send_) :
        send(send_) {}
protected:
    send_function send;
};

class IConnectionFactory
{
public:
    virtual IConnection* create(IConnection::send_function send_) = 0;
    virtual ~IConnectionFactory() {}
};

class HelloConnection : public IConnection
{
    public:
        HelloConnection(IConnection::send_function send_) :
            IConnection(send_) {}
        void receive(const std::string &str) {
            std::cout << "Received: " << str << std::endl;
            std::cout << "Sending Reply: \"Hello\"" << std::endl;
            send("Hello");
        }
};

class HelloConnectionFactory : public IConnectionFactory
{
    public:
        IConnection* create(IConnection::send_function send_) {
            return new HelloConnection(send_);
        }
};

class SimpleServer // <-- IMPLEMENT THIS CLASS!
{
    public:
        SimpleServer(int portno, IConnectionFactory *connection_factory) {}
        void run() {}
};

int main(int argc, const char *argv[])
{
    SimpleServer server(1234, new HelloConnectionFactory);
    server.run();
    return 0;
}

So, it goes like this: IConnection is the virtual interface for implementing a connection. That is, for every new connection, a new instance of an IConnection implementation is spawned, that is bound to that connection. When the connection is closed, the instance is deleted.

The IConnection receives a function pointer as argument, so that it can send replies. You can see how this is supposed to work in the example: “HelloConnection”. That example simple prints the received string on stdout, and sends “Hello” back.

SimpleServer is the class that you need to implement, here you can have all the bookkeeping, and you are probably going to need some internal connection class, that handles  each socket created, etc.

Anyways, I will probably be implementing the SimpleServer myself this week, so I might be able to post a follow up with a solution.

But anyways, this task is simple enough, that a veteran C++ programmer should be able to do it. And it is definitely intended as a practice to work one ones programming skill, so go ahead and try it.

Post your solution in the comments, or send them via email: richard.spindler@gmail.com

If you send via mail, I will add your solution to a follow-up post. 🙂

Have fun,
Cheers
-Richard