Home > C++11 > Spike To Learn

Spike To Learn


As one of the responsibilities on my last project, I had to interface one of our radars to a 10+ year old, legacy, command-and-control system built by another company.  My C++11 code was required to receive commands from the control system and send radar data to it via UDP datagrams over a LAN that connects the two systems together.

Radar CC

It’s unfortunate, but we won’t get a standard C++ networking library until the next version of the C++ standard gets ratified in 2017. However, instead of using the low-level C sockets API to implement the interface functionality, I chose to use the facilities of the Poco::Net library.

PocoNet

Poco is a portable, well written, and nicely documented set of multi-function, open source C++ libraries. Among other nice, higher level, TCP/IP and http networking functionality, Poco::Net provides a thin wrapper layer around the native OS C-language sockets API.

Since I had never used the Poco::Net API before, I decided to spike off the main trail and write a little test program to learn the API before integrating the API calls directly into my production code. I use the “Spike To Learn” best practice whenever I can.

Here is the finished and prettied-up spike program for your viewing pleasure:

#include <string>
#include <iostream>
#include "Poco/Net/SocketAddress.h"
#include "Poco/Net/DatagramSocket.h"
using Poco::Net::SocketAddress;
using Poco::Net::DatagramSocket;

int main() {

	//simulate a UDP legacy app bound to port 15001
	SocketAddress legacyNodeAddr{"localhost", 15001};
	DatagramSocket legacyApp{legacyNodeAddr}; //create & bind

	//simulate my UDP app bound to port 15002
	SocketAddress myAddr{"localhost", 15002};
	DatagramSocket myApp{myAddr}; //create &amp; bind

	//myApp creates & transmits a message
	//encapsulated in a UDP datagram to the legacyApp
	char myAppTxBuff[]{"Hello legacyApp"};
	auto msgSize = sizeof(myAppTxBuff);
	myApp.sendTo(myAppTxBuff,
                     msgSize,
                     legacyNodeAddr);

	//legacyApp receives a message
	//from myApp and prints its payload
	//to the console
	char legacyAppRxBuff[msgSize];
	legacyApp.receiveBytes(legacyAppRxBuff, msgSize);
	std::cout << std::string{legacyAppRxBuff}
	          << std::endl;

	//legacyApp creates & transmits a message
	//to myApp
	char legacyAppTxBuff[]{"Hello myApp!"};
	msgSize = sizeof(legacyAppTxBuff);
	legacyApp.sendTo(legacyAppTxBuff,
                         msgSize,
                         myAddr);

	//myApp receives a message
	//from legacyApp and prints its payload
	//to the console
	char myAppRxBuff[msgSize];
	myApp.receiveBytes(myAppRxBuff, msgSize);
	std::cout << std::string{myAppRxBuff}
	          << std::endl;

}

As you can see, I used the Poco::Net::SocketAddress and Poco::Net::DatagramSocket classes to simulate the bi-directional messaging between myApp and the legacyApp on one machine. The code first transmits the text message “Hello legacyApp!” from myApp to the legacyApp; and then it transmits the text message “Hello myApp!” from the legacyApp to myApp.

 

loopback

 

Lest you think the program doesn’t work 🙂 , here is the console output after the final compile & run cycle:

PocoTest Output

As a side note, notice that I used C++11 brace-initializers to uniformly initialize every object in the code – except for one: the msgSize object. I had to fallback and use the “=” form of initialization because “auto” does not yet play well with brace-initializers. For who knows why, the type of obj in a statement of the form “auto obj{5};” is deduced to be a std::initializer_list<T> instead of a simple int. I think this strange inconvenience will be fixed in C++17. It may have been fixed already in the recently ratified C++14 standard, but I don’t know for sure. Do you?

  1. September 22, 2014 at 5:36 pm

    Which compiler are you using? Not all compilers are created equal, ISO notwithstanding…

    • September 22, 2014 at 7:34 pm

      Hi Guy. I’m using GCC 4.8.3 over cygwin64 on Windows 8.1. Poco comes with the cygwin distribution.

      I’m fairly sure that the auto-with-braces mismatch is a language specification issue. I recall seeing Scott Meyers complaining about it in one of his video talks.

  2. September 22, 2014 at 5:42 pm

    Ah, Poco doesn’t have a build script for VS2013. Can I be bothered… Looks nice…

  3. September 23, 2014 at 3:11 pm

    That’s ringing a bell actually. I love auto, but I tend to initialise by assignment using constructs like
    auto foo = Type{bar};
    or
    auto foo2 = bar();
    and relying on the compiler eliding the assignment.

    • September 23, 2014 at 5:17 pm

      Nothing wrong with that personal style. I’d prefer, if auto did indeed work with braces: auto foo{bar}; and auto foo{bar()};. Until auto plays nice with brace initializers, I don’t think the ideal of “uniform initialization” can really be fully achieved.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: