
BoberManager C++ library
v2.0.4
Table of contents
- Overview
- Versions
- Library files
- Message types
- Message format
- BoberManager class description
- Portability
- Build and connect to your project
Overview
The BoberManager C++ library is a UDP message manager designed to handle communication between multiple clients over a network. It uses UDP packets and string-based protocol. It operates on a static port 62000 and provides functionalities to manage client connections, relay messages, and respond to client queries.
BoberManager is general-purpose software: it is not tied to any sector or application, and the developer of a program decides what the program does with it.
Key features include:
- Client Management: maintains a list of connected clients and updates their addresses as needed. It allows clients to communicate via one gate.
- Message Handling: receives messages and forwards each one to the client named by its destination identifier. The BoberManager works together with BoberClient library which is used by applications for communication.
- Request Responses: responds to specific client queries, such as requests for the list of connected clients.
- Log Options: supports log options to print the list of clients, messages, or both for debugging and monitoring purposes.
Communication structure:

The library is built using C++17 and utilizes the UdpSocket library (provides methods to work with UDP sockets). The UdpSocket repository is not a part of the BoberManager repository: it must be in the folder next to the BoberManager folder (see Build and connect to your project). Also the library’s repository includes application which can be run as communication manager. It is compatible with both Linux and Windows, with specific handling for closing processes on the designated port in Linux. Note: the BoberManager library retains a record of every client or service that has connected to it, even if the client disconnects, up to 1024 clients (see run method). This information is preserved until the run(…) method returns. The library doesn’t have any third-party dependency to be installed in OS.
Versions
Table 1 - Library versions.
| Version | Release date | What’s new |
|---|---|---|
| 1.0.0 | 10.04.2025 | - First version of the application. |
| 2.0.0 | 21.04.2025 | - Application has been changed to library format. |
| 2.0.1 | 22.06.2025 | - Updated UdpSocket submodule. |
| 2.0.2 | 07.02.2026 | - Updated UdpSocket submodule. |
| 2.0.3 | 17.07.2026 | - Updated UdpSocket submodule. |
| 2.0.4 | 17.10.2026 | - UdpSocket sub-repository removed: the library expects UdpSocket in the folder next to it. - Method stop() implemented. - Number of clients limited to 1024, control characters are escaped in printed messages and names. - Processes which use the port 62000 are closed without a shell (Linux). - Method run() returns FALSE instead of terminating the program if an exception occurs. - Compiler warning options and exploit mitigation options added to the CMake files. - Documentation corrected. |
Library files
The library is supplied by source code only. The user would be given a set of files in the form of a CMake project (repository). The repository structure is shown below:
CMakeLists.txt ---------------- Main CMake file of the library.
README.md --------------------- This document.
static ------------------------ Folder with the images of this document.
app --------------------------- Folder with the test application source code.
CMakeLists.txt ------------ CMake file of the application.
main.cpp ------------------ C++ source file of the application.
src --------------------------- Folder with the library source code.
CMakeLists.txt ------------ CMake file of the library.
BoberManager.h ------------ Header file with BoberManager class declaration.
BoberManager.cpp ---------- C++ implementation file.
BoberManagerVersion.h ----- Header file which includes library version.
BoberManagerVersion.h.in -- CMake service file to generate version header.
Message types
The BoberManager library supports different types of messages:
- Command - Used to send specific instructions or commands to another service or client. The receiver will send Ack message back if the message accepted or Nack packet if something wrong with message.
- Request - Used to request specific information or actions from another service or client. The receiver will send Response message back or Nack packet if something wrong with message.
- Response - Used to respond to a previously received Request message.
- Notify - Used to send notifications or updates to other services or clients. The receiver will send Ack message back.
- Ack - Acknowledgment message sent to confirm the successful receipt of a message. For Response there is not reply messages.
- Nack - Negative acknowledgment message sent to indicate an error or invalid message format.
If the client for whom the message is intended is not in the list, the BoberManager sends the Nack message back.
Message format
The BoberManager library uses a specific message format for communication between clients. The format is as follows:
[<ID>]/Src:<source>/Dst:<destination>/<type>/<content>
<ID>: A unique identifier for the message. This helps in tracking and correlating messages.<source>: The source client name. This indicates the client that sent the message.<destination>: The destination client name. This indicates the client that should receive the message.<type>: The type of message. This can be a request, response, or any other type of message defined by the application.<content>: The actual content of the message. This can be any data that needs to be communicated between clients.
The BoberManager takes a name from the first Src: and from the first Dst: of a message: the name is the text up to the next / character, so a name must not be empty and must not contain /. The BoberManager relays the message without changes.
Messages examples
-
Client List Request:
[121]/Src:ClientA/Dst:BoberManager/Request/Clients- Src:ClientA: Source client is ClientA
- Dst:BoberManager: Destination is BoberManager
- Request/Clients: Requesting the list of connected clients
Example response (the list contains all clients, including the requester, sorted by name. Names which contain WebServer are not listed):
[121]/Src:BoberManager/Dst:ClientA/Response/Clients:ClientA,ClientB,ClientC -
Request parameter message to Another Client:
[122]/Src:ClientA/Dst:ClientB/Request/Contrast- Src:ClientA: Source client is ClientA
- Dst:ClientB: Destination client is ClientB
- Request/Contrast: Requesting Contrast parameter from ClientB
Example response:
[122]/Src:ClientB/Dst:ClientA/Response/Contrast:50 -
Command message to set parameter value message to Another Client:
[123]/Src:ClientA/Dst:ClientB/Command/Contrast:78- Src:ClientA: Source client is ClientA
- Dst:ClientB: Destination client is ClientB
- Command/Contrast:78: Calling command to set parameter value
Example response:
[123]/Src:ClientB/Dst:ClientA/Ack
BoberManager class description
BoberManager class declaration
BoberManager class declared in BoberManager.h file. Class declaration:
namespace rapidpixel
{
/// Bober Manager class.
class BoberManager
{
public:
/// Get version.
static std::string getVersion();
/// Class constructor.
BoberManager() = default;
/// Class destructor.
~BoberManager() = default;
/// Copy constructor (deleted).
BoberManager(const BoberManager& src) = delete;
/// Move constructor (deleted).
BoberManager(BoberManager&& src) = delete;
/// Copy assignment operator (deleted).
BoberManager& operator=(const BoberManager& src) = delete;
/// Move assignment operator (deleted).
BoberManager& operator=(BoberManager&& src) = delete;
/// Run Bober Manager.
bool run(bool printClients, bool printMessages);
/// Stop Bober Manager.
void stop();
};
}
getVersion method
The getVersion() method returns string of current class version. Method declaration:
static std::string getVersion();
Method can be used without BoberManager class instance:
std::cout << "BoberManager v: " << rapidpixel::BoberManager::getVersion();
Console output:
BoberManager v: 2.0.4
run method
The run(…) method opens the 62000 UDP port on all local IPv4 interfaces and processes the messages of clients. This is blocking method. It returns control when stop(…) is called or when the manager can not start. The list of clients is created by the method and is deleted when the method returns. Method declaration:
bool run(bool printClients, bool printMessages);
| Parameter | Value |
|---|---|
| printClients | If TRUE the method will print the list of clients to stdout when the number of clients changes. The list is printed as Clients: and the names separated by spaces, between two lines of dashes. |
| printMessages | If TRUE the method will print all received messages to stdout in the format [HH:MM:SS] RX: message. |
Returns: TRUE if the method was stopped by stop(…) or FALSE if the UDP port can not be opened, if the command which closes the processes on the port (Linux) can not be started or if an exception (for example std::bad_alloc) occurred. Errors are written to stderr.
Linux: before the method opens the port it closes all applications which use the 62000 UDP port. The method runs the command sudo fuser -k 62000/udp (without a shell, sudo and fuser are taken from /usr/bin, /bin, /usr/sbin or /sbin, the variable PATH is not used). The application must be allowed to run this command (for example the application must run from sudo). The method waits for the command to finish and does not check its exit status. If sudo or fuser is not found the command is not run. The port is not closed on Windows.
Message limits: the manager ignores a datagram of 11 bytes or less. A datagram longer than 2048 bytes is cut to 2048 bytes on Linux: the first 2048 bytes are processed and relayed (on Windows the read of such a datagram fails and the datagram is ignored). The manager keeps up to 1024 clients: a message of a new client is answered with Nack (the client is not added) if the list is full. A message from a client which is already in the list always updates its address. Control characters (code below 0x20 or 0x7F) in the printed messages and names are printed as \xNN (NN is the hexadecimal code).
Thread safety: the method must not be called from several threads at the same time for the same object. stop(…) can be called from another thread. The object must not be destroyed while the method is executing: call stop(…) and wait until the method returns.
stop method
The stop(…) method stops run(…) method execution. After calling stop(…) method the run(…) method will stop execution (will return control) within 100 ms. The method can be called from any thread. A call made before run(…) has opened the port has no effect: run(…) clears the stop request when it starts to process messages. Method declaration:
void stop();
Example
The example shows how to make application based on BoberManager class:
#include <iostream>
#include <string>
#include "BoberManager.h"
int main(int argc, char** argv)
{
rapidpixel::BoberManager boberManager;
std::cout << "BoberManager v" << rapidpixel::BoberManager::getVersion() << std::endl;
// Check manual run command.
bool printClients = false;
bool printMessages = false;
if (argc > 1)
{
if (std::string(argv[1]) == "-p")
{
printClients = true;
}
else if (std::string(argv[1]) == "-m")
{
printMessages = true;
}
else if (std::string(argv[1]) == "-pm")
{
printClients = true;
printMessages = true;
}
else if (std::string(argv[1]) == "-h")
{
std::cout << "Usage: " << argv[0] << " [-p | -m | -pm]" << std::endl;
std::cout << " -p Print clients list." << std::endl;
std::cout << " -m Print messages." << std::endl;
std::cout << " -pm Print clients list and messages." << std::endl;
return 0;
}
else
{
std::cerr << "Invalid argument. Use -p for clients list or -m for messages." << std::endl;
return 0;
}
}
// Init and run BoberManager.
if (!boberManager.run(printClients, printMessages))
{
std::cerr << "Failed to run BoberManager." << std::endl;
return 0;
}
return 0;
}
Portability
The messages are text: the code does not depend on the byte order or on the size of integer types. The network functions are provided by the UdpSocket library (POSIX sockets on Linux and Winsock on Windows). Closing of the processes which use the 62000 port is implemented for Linux only (see run method). The library is built and tested on Linux with GCC 11 and GCC 12 for x86-64 and with GCC 11 for aarch64 (little endian).
Build and connect to your project
Build stand alone
The repository does not contain sub-repositories. The UdpSocket library which BoberManager depends on must be cloned into the same folder as BoberManager. The folder structure must be:
<work folder>
BoberManager
UdpSocket
Typical commands to build the library and the application (use the URLs of the repositories provided to you):
git clone <BoberManager repository URL>
git clone <UdpSocket repository URL>
cd BoberManager
mkdir build
cd build
cmake ..
make
On Windows use cmake --build . --config Release instead of make. If BoberManager is the top-level CMake project, the main CMakeLists.txt file adds the folder ../UdpSocket before the library itself. If the folder does not exist CMake stops with an error. The application is built as bin/BoberManagerApp in the build folder (see Example).
CMake options
Table 2 - CMake options of the repository. In the options below ${PARENT} is the prefix defined by the top-level project (empty if BoberManager is the top-level project).
| Option | Default | Description |
|---|---|---|
| ${PARENT}_BOBER_MANAGER | ON | Build the library. |
| ${PARENT}_BOBER_MANAGER_APP | ON (stand alone), OFF (included in other project) | Build the application. |
| ${PARENT}_SUBMODULE_CACHE_OVERWRITE | ON | Forced rewriting of the options above in the CMake cache. The top-level project sets it to OFF when it includes BoberManager as a sub-repository. |
| CMAKE_BUILD_TYPE | Release (if not specified) | Build type. |
Connect to your project
If you want connect BoberManager library to your CMake project as source code you can make follow. The BoberManager repository does not contain the UdpSocket library and does not add it when it is included in another project: your project must add UdpSocket. If your project does not add it the compiler stops with the error UdpSocket.h: No such file or directory. For example, if your repository has structure:
CMakeLists.txt
src
CMakeLists.txt
yourLib.h
yourLib.cpp
Create 3rdparty folder in your repository and copy (or add as sub-repositories) UdpSocket and BoberManager repository folders there. The structure of your repository will be:
CMakeLists.txt
src
CMakeLists.txt
yourLib.h
yourLib.cpp
3rdparty
UdpSocket
BoberManager
Create CMakeLists.txt file in 3rdparty folder. CMakeLists.txt should contain:
cmake_minimum_required(VERSION 3.13)
################################################################################
## 3RD-PARTY
## dependencies for the project
################################################################################
project(3rdparty LANGUAGES CXX)
################################################################################
## SETTINGS
## basic 3rd-party settings before use
################################################################################
# To inherit the top-level architecture when the project is used as a submodule.
SET(PARENT ${PARENT}_YOUR_PROJECT_3RDPARTY)
# Disable self-overwriting of parameters inside included subdirectories.
SET(${PARENT}_SUBMODULE_CACHE_OVERWRITE OFF CACHE BOOL "" FORCE)
################################################################################
## CONFIGURATION
## 3rd-party submodules configuration
################################################################################
SET(${PARENT}_SUBMODULE_UDP_SOCKET ON CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_UDP_SOCKET)
SET(${PARENT}_UDP_SOCKET ON CACHE BOOL "" FORCE)
SET(${PARENT}_UDP_SOCKET_EXAMPLES OFF CACHE BOOL "" FORCE)
endif()
SET(${PARENT}_SUBMODULE_BOBER_MANAGER ON CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_BOBER_MANAGER)
SET(${PARENT}_BOBER_MANAGER ON CACHE BOOL "" FORCE)
SET(${PARENT}_BOBER_MANAGER_APP OFF CACHE BOOL "" FORCE)
endif()
################################################################################
## INCLUDING SUBDIRECTORIES
## Adding subdirectories according to the 3rd-party configuration
################################################################################
if (${PARENT}_SUBMODULE_UDP_SOCKET)
add_subdirectory(UdpSocket)
endif()
if (${PARENT}_SUBMODULE_BOBER_MANAGER)
add_subdirectory(BoberManager)
endif()
File 3rdparty/CMakeLists.txt adds folders UdpSocket and BoberManager (in this order: a library is added after the libraries it depends on) to your project and excludes the examples and the application from compiling (by default they are excluded from compiling if the repositories are included as sub-repositories). The structure of your repository will be:
CMakeLists.txt
src
CMakeLists.txt
yourLib.h
yourLib.cpp
3rdparty
CMakeLists.txt
UdpSocket
BoberManager
Next you need include folder 3rdparty in main CMakeLists.txt file of your repository. Add string at the end of your main CMakeLists.txt:
add_subdirectory(3rdparty)
Next you have to include BoberManager library in your src/CMakeLists.txt file:
target_link_libraries(${PROJECT_NAME} BoberManager)
The UdpSocket library is connected to your target together with BoberManager.
Done!