
A header-only library for building asynchronous network services.
Features
- Header-only - No compilation required, just include and go
- TCP and UDP support - Both protocols with the same consistent API
Requirements
- C++20 compiler (GCC 10+, Clang 13+, MSVC 2022+)
- CMake 3.28+
- Ninja (recommended build system)
- Linux (other platforms may work but are untested)
Installation
Using CPM (Recommended)
Add cppnet to your CMake project using CPM:
include(cmake/CPM.cmake)
CPMAddPackage("gh:kcexn/cppnet@0.9.0")
target_link_libraries(your_target PRIVATE cppnet)
Using FetchContent
include(FetchContent)
FetchContent_Declare(
cppnet
GIT_REPOSITORY https://github.com/kcexn/cppnet.git
GIT_TAG v0.9.0
)
FetchContent_MakeAvailable(cppnet)
target_link_libraries(your_target PRIVATE cppnet)
Manual Installation
git clone https://github.com/kcexn/cppnet.git
cd cppnet
cmake --preset release
sudo cmake --install build/release
Example Applications
Some simple examples of applications built with cppnet:
Quick Start
TCP Echo Server
#include <arpa/inet.h>
template <typename T>
explicit echo_service(socket_address<T> address) : Base(address) {}
auto initialize(const socket_handle &socket) -> std::error_code {
return {};
}
auto stop() -> void {
}
std::shared_ptr<read_context> rctx,
std::span<const std::byte> buf) -> void {
using namespace io::socket;
using namespace stdexec;
sender auto echo_sender =
io::sendmsg(socket, socket_message{.buffers = buf}, 0) |
then([&, socket, rctx](auto &&) {
submit_recv(ctx, socket, std::move(rctx));
}) |
upon_error([](auto &&) {});
ctx.scope.spawn(std::move(echo_sender));
}
};
int main() {
auto addr = io::socket::socket_address<sockaddr_in>();
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = INADDR_ANY;
addr->sin_port = htons(8080);
ctx.start(addr);
ctx.state.wait(async_context::STARTED);
return 0;
}
A ServiceLike Async TCP Service.
Definition async_tcp_service.hpp:73
A threaded asynchronous service.
Definition context_thread.hpp:57
This file exports the public cppnet interface.
This namespace is for network services.
Definition async_context.hpp:31
An asynchronous execution context.
Definition async_context.hpp:34
UDP Echo Server
#include <arpa/inet.h>
template <typename T>
explicit udp_echo_service(socket_address<T> address) : Base(address) {}
std::shared_ptr<read_context> rctx,
std::span<const std::byte> buf) -> void {
using namespace io::socket;
using namespace stdexec;
sender auto echo_sender =
io::sendmsg(socket, rctx->msg, 0) |
then([&, socket, rctx](auto &&) {
submit_recv(ctx, socket, std::move(rctx));
}) |
upon_error([](auto &&) {});
ctx.scope.spawn(std::move(echo_sender));
}
};
int main() {
auto addr = io::socket::socket_address<sockaddr_in>();
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = INADDR_ANY;
addr->sin_port = htons(8080);
ctx.start(addr);
ctx.state.wait(async_context::STARTED);
return 0;
}
A ServiceLike Async UDP Service.
Definition async_udp_service.hpp:66
Client Factories
class client_factory {
public:
struct client_t {
};
auto make_client() -> client_t
{
if (ctx_.state == async_context::PENDING)
ctx_.start();
return {.ctx = std::addressof(ctx_)};
}
private:
};
basic_context_thread< detail::null_service > context_thread
Default context thread is a null service thread.
Definition context_thread.hpp:101
Building from Source
# Clone the repository
git clone https://github.com/kcexn/cloudbus-net.git
cd cloudbus-net
# Debug build (with tests and coverage)
cmake --preset debug
cmake --build --preset debug
# Release build (optimized)
cmake --preset release
cmake --build --preset release
# Run tests
ctest --preset debug --output-on-failure
Documentation
Generate API documentation with Doxygen:
cmake --preset debug -DCPPNET_BUILD_DOCS=ON
cmake --build --preset debug --target doxygen
Documentation will be in build/debug/docs/html/index.html.
Architecture
The library uses the CRTP (Curiously Recurring Template Pattern) for services:
- **
async_context** - Execution context with async_scope, I/O multiplexer, signal handling, and event loop timers
- **
context_thread<Service>** - Runs a service in a dedicated thread (default null_service is useful for network clients)
- **
async_tcp_service<Handler>** - TCP server base class with accept/read loop
- **
async_udp_service<Handler>** - UDP server base class with read loop
- **
timers<InterruptSource>** - Event-loop timers for scheduling callbacks
Your service inherits from the appropriate template and implements:
service() to handle received data (required - must call submit_recv() to continue)
initialize() to configure the socket (optional)
stop() for graceful shutdown (optional, TCP only)
Signal Handling
Services support two signals:
terminate (0) - Graceful shutdown
user1 (1) - Custom application signal
Send signals via async_context::signal(int signum).
License
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
Contributing
Contributions are welcome! Please ensure:
- Code follows C++20 best practices
- All tests pass (
ctest --preset debug)
- New features include tests and documentation
- Code coverage is maintained
Dependencies
All dependencies are automatically fetched via CPM: