A small, modern C++17 library for controlling a KMBox NET device over UDP. It provides a typed, thread-safe API for mouse movement, buttons, scrolling, keyboard HID input, automatic movement, and Bezier movement without exposing WinSock or protocol packet structures to applications.
- C++17 with no third-party runtime dependencies
- Windows and Linux support
- RAII connection management; no global socket or singleton state
- Thread-safe commands and per-client input state
- Strict UUID, argument, response-command, and sequence validation
- Exact-width, explicitly serialized protocol packets
- Optional fire-and-forget mode for latency-sensitive movement
- CMake package export, install rules, example, and hardware-free protocol tests
- Static or shared library builds through standard CMake
BUILD_SHARED_LIBS
- A C++17 compiler (Visual Studio 2019+, GCC 9+, or Clang 10+)
- CMake 3.20+
- A KMBox NET device and the address, UDP port, and eight-hex-digit UUID shown by the device
cmake -S . -B build -DKMBOXNET_BUILD_TESTS=ON -DKMBOXNET_BUILD_EXAMPLES=ON
cmake --build build --config Release
ctest --test-dir build -C Release --output-on-failureOr use the included Ninja preset:
cmake --preset default
cmake --build --preset default
ctest --preset defaultInstalled package:
find_package(KmBoxNet CONFIG REQUIRED)
target_link_libraries(your_target PRIVATE KmBoxNet::KmBoxNet)As a subdirectory or with FetchContent:
add_subdirectory(path/to/CPP-KmBoxNet)
target_link_libraries(your_target PRIVATE KmBoxNet::KmBoxNet)#include <kmboxnet/hid.hpp>
#include <kmboxnet/kmboxnet.hpp>
#include <chrono>
#include <iostream>
int main() {
kmbox::net::Config config;
config.address = "192.168.2.188";
config.port = 6400;
config.uuid = "A1B2C3D4";
kmbox::net::Client device;
if (const auto result = device.connect(config); !result) {
std::cerr << "KMBox NET: " << result.message() << '\n';
return 1;
}
using namespace std::chrono_literals;
if (const auto result = device.move_auto(100, 25, 250ms); !result) {
std::cerr << result.message() << '\n';
}
device.click(kmbox::net::MouseButton::left);
const auto key = kmbox::net::usage(kmbox::net::HidKey::a);
device.key_down(key);
device.key_up(key);
}All commands return kmbox::net::Result. A successful result converts to true; failures expose a library Error, a stable message, and an underlying socket error when one exists.
Client::connect(config)
Client::disconnect()
Client::is_connected()
Client::move(x, y)
Client::move_auto(x, y, duration)
Client::move_bezier(destination, duration, control1, control2)
Client::set_button(button, pressed)
Client::button_down(button)
Client::button_up(button)
Client::click(button)
Client::scroll(delta)
Client::set_mouse_state(buttons, x, y, wheel)
Client::key_down(hid_usage)
Client::key_up(hid_usage)
Client::release_all()
Client::reboot()hid.hpp contains common USB HID keyboard usage IDs. Raw usage values are also accepted for keys not listed there. KMBox NET supports up to ten simultaneous non-modifier keys plus the eight standard modifier keys.
The device's response command and sequence number are checked by default. Set Config::validate_responses to false for fire-and-forget commands when minimum latency matters. The initial connection handshake is always validated. With validation disabled, a successful result confirms only that the UDP datagram was accepted by the local socket; UDP cannot guarantee remote delivery.
The implementation follows the KMBox NET v2 UDP packet layout and command identifiers documented by the vendor demo. It serializes every field explicitly instead of sending compiler-dependent C structs. Automated tests use a local UDP device emulator to verify packet sizes, byte order, command IDs, state transitions, and acknowledgement validation.
This project was informed by the public ZCban/kmboxNET vendor demo and the local NET integration supplied for this project. It is an independent library and is not affiliated with or endorsed by the device vendor.
MIT. See LICENSE.