Common System 0.2.0
Common interfaces and patterns for system integration
Loading...
Searching...
No Matches
udp_client_interface.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
15#pragma once
16
17#include <chrono>
18#include <cstdint>
19#include <functional>
20#include <memory>
21#include <optional>
22#include <span>
23#include <string>
24#include <vector>
25
27
28namespace kcenon::common {
29namespace interfaces {
30
37 std::string host;
38
40 uint16_t port = 0;
41
42 udp_endpoint() = default;
43
44 udp_endpoint(std::string host_, uint16_t port_)
45 : host(std::move(host_)), port(port_) {}
46
51 [[nodiscard]] std::string to_string() const {
52 return host + ":" + std::to_string(port);
53 }
54
55 bool operator==(const udp_endpoint& other) const {
56 return host == other.host && port == other.port;
57 }
58
59 bool operator!=(const udp_endpoint& other) const {
60 return !(*this == other);
61 }
62};
63
70 bool dont_fragment = false;
71
73 uint8_t ttl = 0;
74
76 std::chrono::milliseconds timeout{0};
77
78 udp_send_options() = default;
79};
80
87 uint64_t packets_sent = 0;
88
90 uint64_t bytes_sent = 0;
91
93 uint64_t send_failures = 0;
94
96 std::optional<std::chrono::steady_clock::time_point> last_send_time;
97
101 void reset() {
102 packets_sent = 0;
103 bytes_sent = 0;
104 send_failures = 0;
105 last_send_time = std::nullopt;
106 }
107};
108
137public:
138 virtual ~IUdpClient() = default;
139
150 virtual ::kcenon::common::VoidResult connect(const std::string& host, uint16_t port) = 0;
151
157 virtual ::kcenon::common::VoidResult connect(const udp_endpoint& endpoint) {
158 return connect(endpoint.host, endpoint.port);
159 }
160
169 virtual ::kcenon::common::VoidResult send(std::span<const uint8_t> data) = 0;
170
178 virtual ::kcenon::common::VoidResult send(std::span<const uint8_t> data,
179 const udp_send_options& options) {
180 // Default implementation ignores options
181 (void)options;
182 return send(data);
183 }
184
194 virtual ::kcenon::common::VoidResult send_to(std::span<const uint8_t> data,
195 const udp_endpoint& endpoint) = 0;
196
201 [[nodiscard]] virtual bool is_connected() const = 0;
202
207 [[nodiscard]] virtual std::optional<udp_endpoint> get_remote_endpoint() const {
208 return std::nullopt;
209 }
210
217 virtual void disconnect() = 0;
218
223 [[nodiscard]] virtual udp_statistics get_statistics() const {
224 return {};
225 }
226
230 virtual void reset_statistics() {}
231
236 [[nodiscard]] virtual std::string get_implementation_name() const {
237 return "IUdpClient";
238 }
239
240 // Convenience methods for string data
241
247 ::kcenon::common::VoidResult send(const std::string& data) {
248 return send(std::span<const uint8_t>(
249 reinterpret_cast<const uint8_t*>(data.data()),
250 data.size()));
251 }
252
259 ::kcenon::common::VoidResult send_to(const std::string& data, const udp_endpoint& endpoint) {
260 return send_to(std::span<const uint8_t>(
261 reinterpret_cast<const uint8_t*>(data.data()),
262 data.size()), endpoint);
263 }
264};
265
274public:
275 ::kcenon::common::VoidResult connect(const std::string& /*host*/, uint16_t /*port*/) override {
276 return ::kcenon::common::VoidResult(::kcenon::common::error_info{
278 "UDP client not available",
279 "null_udp_client"});
280 }
281
282 ::kcenon::common::VoidResult send(std::span<const uint8_t> /*data*/) override {
283 return ::kcenon::common::VoidResult(::kcenon::common::error_info{
285 "UDP client not available",
286 "null_udp_client"});
287 }
288
289 ::kcenon::common::VoidResult send_to(std::span<const uint8_t> /*data*/,
290 const udp_endpoint& /*endpoint*/) override {
291 return ::kcenon::common::VoidResult(::kcenon::common::error_info{
293 "UDP client not available",
294 "null_udp_client"});
295 }
296
297 [[nodiscard]] bool is_connected() const override {
298 return false;
299 }
300
301 void disconnect() override {}
302
303 [[nodiscard]] std::string get_implementation_name() const override {
304 return "null_udp_client";
305 }
306};
307
311using UdpClientFactory = std::function<std::shared_ptr<IUdpClient>()>;
312
318public:
319 virtual ~IUdpClientProvider() = default;
320
325 virtual std::shared_ptr<IUdpClient> get_udp_client() = 0;
326
331 virtual std::shared_ptr<IUdpClient> create_udp_client() = 0;
332};
333
334} // namespace interfaces
335} // namespace kcenon::common
Result type for error handling with member function support.
Definition core.cppm:165
Interface for modules that provide UDP client implementations.
virtual std::shared_ptr< IUdpClient > create_udp_client()=0
Create a new UDP client.
virtual std::shared_ptr< IUdpClient > get_udp_client()=0
Get the default UDP client instance.
Abstract interface for UDP client implementations.
virtual udp_statistics get_statistics() const
Get send statistics.
::kcenon::common::VoidResult send(const std::string &data)
Send string data to the connected endpoint.
virtual bool is_connected() const =0
Check if the client is connected to an endpoint.
virtual void reset_statistics()
Reset statistics.
virtual::kcenon::common::VoidResult send_to(std::span< const uint8_t > data, const udp_endpoint &endpoint)=0
Send data to a specific endpoint (connectionless)
virtual std::string get_implementation_name() const
Get the implementation name for logging/debugging.
::kcenon::common::VoidResult send_to(const std::string &data, const udp_endpoint &endpoint)
Send string data to a specific endpoint.
virtual::kcenon::common::VoidResult send(std::span< const uint8_t > data)=0
Send data to the connected endpoint.
virtual::kcenon::common::VoidResult connect(const udp_endpoint &endpoint)
Connect to a remote endpoint.
virtual::kcenon::common::VoidResult send(std::span< const uint8_t > data, const udp_send_options &options)
Send data to the connected endpoint with options.
virtual::kcenon::common::VoidResult connect(const std::string &host, uint16_t port)=0
Connect to a remote endpoint for optimized sending.
virtual std::optional< udp_endpoint > get_remote_endpoint() const
Get the currently connected endpoint.
virtual void disconnect()=0
Disconnect from the current endpoint.
Null implementation for when UDP transport is disabled.
::kcenon::common::VoidResult connect(const std::string &, uint16_t) override
Connect to a remote endpoint for optimized sending.
::kcenon::common::VoidResult send(std::span< const uint8_t >) override
Send data to the connected endpoint.
::kcenon::common::VoidResult send_to(std::span< const uint8_t >, const udp_endpoint &) override
Send data to a specific endpoint (connectionless)
std::string get_implementation_name() const override
Get the implementation name for logging/debugging.
bool is_connected() const override
Check if the client is connected to an endpoint.
void disconnect() override
Disconnect from the current endpoint.
constexpr int NOT_INITIALIZED
Definition compat.h:36
std::function< std::shared_ptr< IUdpClient >()> UdpClientFactory
Factory function type for creating UDP client instances.
Core interfaces.
Definition adapter.h:21
Umbrella header for Result<T> type and related utilities.
Standard error information used by Result<T>.
Definition core.cppm:106
Represents a UDP endpoint (host and port)
bool operator!=(const udp_endpoint &other) const
std::string to_string() const
Convert to string representation.
std::string host
Hostname or IP address.
udp_endpoint(std::string host_, uint16_t port_)
bool operator==(const udp_endpoint &other) const
uint8_t ttl
TTL (Time To Live) value, 0 means use system default.
std::chrono::milliseconds timeout
Send timeout (0 means no timeout / non-blocking)
bool dont_fragment
Whether to set the don't-fragment flag (if supported)
Statistics for UDP client operations.
uint64_t send_failures
Number of failed send operations.
uint64_t packets_sent
Total number of packets sent.
uint64_t bytes_sent
Total number of bytes sent.
std::optional< std::chrono::steady_clock::time_point > last_send_time
Timestamp of last successful send.