1. nanomsgxx-design(7)
  2. nanomsgxx
  3. nanomsgxx-design(7)


nanomsgxx-design - Nanomsgxx Design


This chapter exposes the main design decisions that were made when developping nanomsgxx.


nanomsg uses many constants to represent protocols, socket domains, options, flags... Since C++ syntax is mostly compatible with C, standard nanomsg constants (NN) can be simply used wherever constants are expected in the C++ API. However nanomsgxx ports all constants within the nnxx namespace, removing the leading NN_. For example the NN_MSG constant in the C API is ported by the nnxx::MSG symbol. This applies to almost all constants, except in a few cases where it conflicts with some existing symbols (more on that later).


nanomsgxx functions accept string arguments in some cases, to bind or connect to a node for example. Everywhere a string is expected the functions are designed to receive any object that can be converted to a C-string (null-terminted char sequence), this includes:

This feature can be extended by providing a c_str function for new types, for example:

namespace X {
  const char *c_str(const other_string_type &s) {
    return s.c_string();


The nanomsgxx API provides a few object types that abstracts concepts of the C API, while trying to stay as close as possible it adds a few extra types to integrate with the C++ standard library and take advantages of the rich features of the language.

All types in the nanomsgxx API provide a move constructor and a move assignment operator, these are powerful features of C++11 and the library makes heavy use of it to provide an easy resource management model, as well as protecting the user from mis-using the library in some places.

Member functions are used of nanomsgxx objects to provide operations that are part of the object's identity, providing the low-level pieces on which extensions can be built.
For example the nnxx::socket type will have the recv and send member functions because receiving and sending messages are the core features of the this type, but protocol extensions such as turning on or off Nagle's algorithm for TCP connections will be provided as a non-member function because it's not an operation that can be performed on any socket type.


The nanomsg library uses the POSIX mechanism to report errors, setting errno to some error number and returning a nagative number from the function. C++ exceptions are used to report these conditions and almost all exceptions thrown by the nanomsgxx functions are sub-classes of std::system_error, so the original error number that was generated by the underlying nanomsg routine can be accessed through the caught exception.

When a program receives a signal it may cause any ongoing system call to be cancelled to execute a signal handler instead, in that case the systeam call terminates with the EINTR error code. While nanomsg mirrors this behavior, nanomsgxx reports these conditions with the nnxx::signal_error exception.
This can be deactivated on a per-call basis by passing nnxx::NO_SIGNAL_ERROR in the flags argument on any blocking call, you should then refer to the documentation of each function to understand how to handle this case.

nanomsg's API lets the user define a timeout for any blocking operation (typically receiving or sending messages), and reports any timeout in the operation with a nnxx::timeout_error exception.
This can be deactivated on a per-call basis by passing nnxx::NO_TIMEOUT_ERROR in the flags argument on any blocking call, you should then refer to the documentation of each function to understand how to handle this case.

When the program is about to exit it is supposed to inform the nanomsg library by calling nn_term, making any future or pending calls to nanomsg routines failing and setting errno to ETERM. While this is still reported with an exception in nanomsgxx it's on case where the exception thrown isn't a sub-class of std::system_error. The nnxx::term_error exception is instead a sub-class of std::logic_error. That allows the program to handle this condition away from local error handling logic.

The nanomsg library uses dynamic memory allocations in some places, if these fail for whatever reasons the functions report the error with the ENOMEM errno code.
This is another case where nanomsgxx will report an error through an exception that is not a subclass of std::system_error. The C++ standard library provides the std::bad_alloc exception for this purpose, in order to easily integrate with programs that are written for standard C++ nanomsgxx also reports memory allocation failures by throwing an instance of std::bad_alloc.




Achille Roussel

  1. achille.roussel@gmail.com
  2. May 2014
  3. nanomsgxx-design(7)