C++ Challenge: 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

Managing C++ libs with CMake ExternalProject and Git

Writing modular software, you might sooner or later come into the situation, that you have some functionality, that you want to share between different projects. Let’s say, to have built a couple of convenience classes and function that you want to reuse.

There are different ways to skin the cat, one of them might be using a dedicated C++ dependency manager like Biicode. Or a general package manager for your platform of choice, like apt-get on Debian and Ubuntu, or Homebrew on OSX.

Usually you will start with putting your module or library into a git repositry, if you haven’t done that already. For Code that I want publish publicly, I usually choose my github account.

Now for creating a homebrew package, or a debian package, you either need to create some project description, a bit of boilerplate, and need some platform like launchpad to publish packages. Or in the case of biicode, you need an additional account at another platform, and you have to install another tool.

However, there is another approach, that uses software that you probably already have, and that is CMake and Git.

CMake has a functionality called ExternalProject_add, which can use, to automatically check out a git repository, and build that as part of the normal build process.

Of course, the same functionality would be possible with git submodules, but honestly, I always found this part of git rather cumbersome, and unnecessarily complex, for what I want to do.

So, I’ve created two small examples, that show how to create a small library, and link to it through CMake ExternalProject_add:

The first one is the library: cmake_simple_lib

And the second one is the project that uses the library: cmake_simple_demo

I hope you find that useful.

Cheers
-Richard