Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
kcenon::network::internal::udp_socket Class Reference

A lightweight wrapper around asio::ip::udp::socket, enabling asynchronous datagram operations. More...

#include <udp_socket.h>

Inheritance diagram for kcenon::network::internal::udp_socket:
Inheritance graph
Collaboration diagram for kcenon::network::internal::udp_socket:
Collaboration graph

Public Member Functions

 udp_socket (asio::ip::udp::socket socket)
 Constructs a udp_socket by taking ownership of a moved socket.
 
 ~udp_socket ()=default
 Default destructor (no special cleanup needed).
 
auto set_receive_callback (std::function< void(const std::vector< uint8_t > &, const asio::ip::udp::endpoint &)> callback) -> void
 Sets a callback to receive inbound datagrams.
 
auto set_error_callback (std::function< void(std::error_code)> callback) -> void
 Sets a callback to handle socket errors (e.g., receive/send failures).
 
auto start_receive () -> void
 Begins the continuous asynchronous receive loop.
 
auto stop_receive () -> void
 Stops the receive loop to prevent further async operations.
 
auto async_send_to (std::vector< uint8_t > &&data, const asio::ip::udp::endpoint &endpoint, std::function< void(std::error_code, std::size_t)> handler) -> void
 Initiates an asynchronous send of the given data to endpoint.
 
auto socket () -> asio::ip::udp::socket &
 Provides direct access to the underlying asio::ip::udp::socket in case advanced operations are needed.
 
auto close () -> void
 Safely closes the socket and stops all async operations.
 
auto is_closed () const -> bool
 Checks if the socket has been closed.
 

Private Member Functions

auto do_receive () -> void
 Internal function to handle the receive logic with async_receive_from().
 

Private Attributes

asio::ip::udp::socket socket_
 
std::array< uint8_t, 65536 > read_buffer_
 
asio::ip::udp::endpoint sender_endpoint_
 
std::mutex callback_mutex_
 
std::function< void(const std::vector< uint8_t > &, const asio::ip::udp::endpoint &)> receive_callback_
 
std::function< void(std::error_code)> error_callback_
 
std::atomic< bool > is_receiving_ {false}
 
std::atomic< bool > is_closed_ {false}
 

Detailed Description

A lightweight wrapper around asio::ip::udp::socket, enabling asynchronous datagram operations.

Key Features

Thread Safety

  • All public methods are thread-safe. Callback registration is protected by callback_mutex_.
  • ASIO operations are serialized through the io_context, ensuring read_buffer_ is only accessed by one async operation at a time.
  • The provided callbacks will be invoked on an ASIO worker thread; ensure that your callback logic is thread-safe if it shares data.

UDP Characteristics

  • Connectionless: Each datagram is independent.
  • No guaranteed delivery: Packets may be lost, duplicated, or reordered.
  • Message boundaries preserved: Each receive corresponds to one send.

Definition at line 46 of file udp_socket.h.

Constructor & Destructor Documentation

◆ udp_socket()

kcenon::network::internal::udp_socket::udp_socket ( asio::ip::udp::socket socket)

Constructs a udp_socket by taking ownership of a moved socket.

Parameters
socketAn asio::ip::udp::socket that must be open or at least valid.

After construction, you can call start_receive() to begin receiving datagrams. For sending, call async_send_to().

Definition at line 12 of file udp_socket.cpp.

13 : socket_(std::move(socket))
14 {
15 // constructor body empty
16 }
auto socket() -> asio::ip::udp::socket &
Provides direct access to the underlying asio::ip::udp::socket in case advanced operations are needed...
Definition udp_socket.h:137

◆ ~udp_socket()

kcenon::network::internal::udp_socket::~udp_socket ( )
default

Default destructor (no special cleanup needed).

Member Function Documentation

◆ async_send_to()

auto kcenon::network::internal::udp_socket::async_send_to ( std::vector< uint8_t > && data,
const asio::ip::udp::endpoint & endpoint,
std::function< void(std::error_code, std::size_t)> handler ) -> void

Initiates an asynchronous send of the given data to endpoint.

Parameters
dataThe buffer to send over UDP (moved for efficiency).
endpointThe target asio::ip::udp::endpoint to send to.
handlerA completion handler with signature void(std::error_code, std::size_t) invoked upon completion.

The handler receives:

  • ec : the std::error_code from the send operation,
  • bytes_transferred : how many bytes were actually sent.

Example

auto sock = std::make_shared<kcenon::network::internal::udp_socket>(...);
std::vector<uint8_t> buf = {0x01, 0x02, 0x03};
asio::ip::udp::endpoint target(asio::ip::address::from_string("127.0.0.1"), 8080);
sock->async_send_to(std::move(buf), target,
[](std::error_code ec, std::size_t len) {
if(ec) {
// handle error
} else {
// handle success
}
});
Note
Data is moved (not copied) to avoid memory allocation.
The original vector will be empty after this call.

Definition at line 123 of file udp_socket.cpp.

127 {
128 auto self = shared_from_this();
129 // Move data into shared_ptr for lifetime management
130 auto buffer = std::make_shared<std::vector<uint8_t>>(std::move(data));
131 socket_.async_send_to(
132 asio::buffer(*buffer),
133 endpoint,
134 [handler = std::move(handler), self, buffer](std::error_code ec,
135 std::size_t bytes_transferred)
136 {
137 if constexpr (std::is_invocable_v<decltype(handler),
138 std::error_code, std::size_t>)
139 {
140 if (handler)
141 {
142 handler(ec, bytes_transferred);
143 }
144 }
145 });
146 }

◆ close()

auto kcenon::network::internal::udp_socket::close ( ) -> void

Safely closes the socket and stops all async operations.

This method atomically sets the closed flag before closing the socket, preventing data races between the close operation and async receive operations. Thread-safe with respect to concurrent async operations.

Definition at line 46 of file udp_socket.cpp.

47 {
48 // Set closed flag first to prevent new operations
49 is_closed_.store(true);
51
52 // Close the socket
53 std::error_code ec;
54 socket_.close(ec);
55 // Errors during close are intentionally ignored
56 }
auto stop_receive() -> void
Stops the receive loop to prevent further async operations.

◆ do_receive()

auto kcenon::network::internal::udp_socket::do_receive ( ) -> void
private

Internal function to handle the receive logic with async_receive_from().

Upon success, it calls receive_callback_ if set with both data and sender endpoint, then schedules another receive. On error, it calls error_callback_ if available.

Definition at line 63 of file udp_socket.cpp.

64 {
65 // Check if receiving has been stopped before initiating new async operation
66 if (!is_receiving_.load())
67 {
68 return;
69 }
70
71 auto self = shared_from_this();
72 socket_.async_receive_from(
73 asio::buffer(read_buffer_),
75 [this, self](std::error_code ec, std::size_t length)
76 {
77 // Check if receiving has been stopped at callback time
78 if (!is_receiving_.load())
79 {
80 return;
81 }
82
83 if (ec)
84 {
85 // On error, invoke the error callback
86 if constexpr (std::is_invocable_v<decltype(error_callback_),
87 std::error_code>)
88 {
89 std::lock_guard<std::mutex> lock(callback_mutex_);
91 {
93 }
94 }
95 return;
96 }
97
98 // On success, if length > 0, build a vector and call receive_callback_
99 if (length > 0)
100 {
101 if constexpr (std::is_invocable_v<decltype(receive_callback_),
102 const std::vector<uint8_t>&,
103 const asio::ip::udp::endpoint&>)
104 {
105 std::vector<uint8_t> datagram(read_buffer_.begin(),
106 read_buffer_.begin() + length);
107 std::lock_guard<std::mutex> lock(callback_mutex_);
109 {
111 }
112 }
113 }
114
115 // Continue receiving only if still active
116 if (is_receiving_.load())
117 {
118 do_receive();
119 }
120 });
121 }
auto do_receive() -> void
Internal function to handle the receive logic with async_receive_from().
asio::ip::udp::endpoint sender_endpoint_
Definition udp_socket.h:167
std::array< uint8_t, 65536 > read_buffer_
Definition udp_socket.h:166
std::function< void(const std::vector< uint8_t > &, const asio::ip::udp::endpoint &)> receive_callback_
Definition udp_socket.h:171
std::function< void(std::error_code)> error_callback_
Definition udp_socket.h:173

◆ is_closed()

auto kcenon::network::internal::udp_socket::is_closed ( ) const -> bool
nodiscard

Checks if the socket has been closed.

Returns
true if close() has been called on this socket.

Definition at line 58 of file udp_socket.cpp.

59 {
60 return is_closed_.load();
61 }

References is_closed_.

◆ set_error_callback()

auto kcenon::network::internal::udp_socket::set_error_callback ( std::function< void(std::error_code)> callback) -> void

Sets a callback to handle socket errors (e.g., receive/send failures).

Parameters
callbackA function with signature void(std::error_code), invoked when any asynchronous operation fails.

If no callback is set, errors are not explicitly handled here (beyond stopping receives).

Definition at line 26 of file udp_socket.cpp.

28 {
29 std::lock_guard<std::mutex> lock(callback_mutex_);
30 error_callback_ = std::move(callback);
31 }

◆ set_receive_callback()

auto kcenon::network::internal::udp_socket::set_receive_callback ( std::function< void(const std::vector< uint8_t > &, const asio::ip::udp::endpoint &)> callback) -> void

Sets a callback to receive inbound datagrams.

Parameters
callbackA function with signature void(const std::vector<uint8_t>&, const asio::ip::udp::endpoint&), called whenever a datagram is successfully received. The first parameter is the data, the second is the sender's endpoint.

If no callback is set, received data is effectively discarded.

Definition at line 18 of file udp_socket.cpp.

21 {
22 std::lock_guard<std::mutex> lock(callback_mutex_);
23 receive_callback_ = std::move(callback);
24 }

◆ socket()

auto kcenon::network::internal::udp_socket::socket ( ) -> asio::ip::udp::socket&
inline

Provides direct access to the underlying asio::ip::udp::socket in case advanced operations are needed.

Returns
A reference to the wrapped asio::ip::udp::socket.

Definition at line 137 of file udp_socket.h.

137{ return socket_; }

References socket_.

◆ start_receive()

auto kcenon::network::internal::udp_socket::start_receive ( ) -> void

Begins the continuous asynchronous receive loop.

Once called, the class repeatedly calls async_receive_from(). If an error occurs, error_callback_ is triggered, stopping further receives.

Definition at line 33 of file udp_socket.cpp.

34 {
35 // Set receiving flag and kick off the initial receive loop
36 is_receiving_.store(true);
37 do_receive();
38 }

◆ stop_receive()

auto kcenon::network::internal::udp_socket::stop_receive ( ) -> void

Stops the receive loop to prevent further async operations.

Definition at line 40 of file udp_socket.cpp.

41 {
42 // Stop further receive operations
43 is_receiving_.store(false);
44 }

Member Data Documentation

◆ callback_mutex_

std::mutex kcenon::network::internal::udp_socket::callback_mutex_
private

Protects callback registration and access.

Definition at line 169 of file udp_socket.h.

◆ error_callback_

std::function<void(std::error_code)> kcenon::network::internal::udp_socket::error_callback_
private

Error callback.

Definition at line 173 of file udp_socket.h.

◆ is_closed_

std::atomic<bool> kcenon::network::internal::udp_socket::is_closed_ {false}
private

Flag to indicate socket is closed.

Definition at line 176 of file udp_socket.h.

176{false};

Referenced by is_closed().

◆ is_receiving_

std::atomic<bool> kcenon::network::internal::udp_socket::is_receiving_ {false}
private

Flag to prevent receive after stop.

Definition at line 175 of file udp_socket.h.

175{false};

◆ read_buffer_

std::array<uint8_t, 65536> kcenon::network::internal::udp_socket::read_buffer_
private

Buffer for receiving datagrams (max UDP size).

Definition at line 166 of file udp_socket.h.

◆ receive_callback_

std::function<void(const std::vector<uint8_t>&, const asio::ip::udp::endpoint&)> kcenon::network::internal::udp_socket::receive_callback_
private

Inbound datagram callback.

Definition at line 171 of file udp_socket.h.

◆ sender_endpoint_

asio::ip::udp::endpoint kcenon::network::internal::udp_socket::sender_endpoint_
private

Stores the sender's endpoint during receive.

Definition at line 167 of file udp_socket.h.

◆ socket_

asio::ip::udp::socket kcenon::network::internal::udp_socket::socket_
private

The underlying ASIO UDP socket.

Definition at line 164 of file udp_socket.h.

Referenced by socket().


The documentation for this class was generated from the following files: