diff --git a/README.md b/README.md index d31c761..e43d609 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # Socketwrapper - Simple to use linux socket/networking library + [Documentation is work in progress] Currently this is a header-only library containing classes for TCP and UDP -network connections. There are also classes for TLS encrypted TCP sockets, which requires to link +network connections. There are also classes for TLS encrypted TCP sockets, which requires to link against OpenSSL (use the compile flags `-lssl -lcrypto`) and some other utility functions. @@ -10,14 +11,178 @@ The only requirements are a C++17 compliant compiler (make sure to compile with this version!), and `pthreads` (you need to link with `lpthread`) and OpenSSL (but only if you use the `tls.hpp` header). +C++20 or higher is required when using the coroutine-based asynchronous API. + There are some examples for all socket/connection types in the `examples` directory. -## Asyncronous functionality: -*TODO Describe the design of the asynchronous system* +## Asynchronous functionality + +Socketwrapper provides three ways to perform asynchronous networking operations: + +* **Callback-based operations** using `async_read()`, `async_send()`, and `async_accept()` +* **Future-based operations** using `promised_read()`, `promised_send()`, and `promised_accept()` +* **C++20 coroutine operations** using the awaitable overloads of `async_read()`, `async_send()` / `async_write()`, and `async_accept()` + +### Callback-based operations + +The callback-based functions immediately return and invoke the supplied callback when the asynchronous operation has completed. + +For example: + +```cpp +char buffer[1024]; + +connection.async_read(net::span(buffer), + [](size_t bytes_read) + { + // Handle received data + }); +``` + +The asynchronous context must be run using `net::async_run()`: + +```cpp +net::async_run(); +``` + +`async_run()` blocks the current thread until all registered asynchronous operations have been handled and their completion callbacks have finished executing. + +### Future-based operations + +Socketwrapper also provides asynchronous operations that return a `std::future`. These functions allow the caller to start an operation immediately and retrieve its result later. + +For TCP connections: + +```cpp +char buffer[1024]; + +std::future result = + connection.promised_read(net::span(buffer)); + +// Do other work... + +size_t bytes_read = result.get(); +``` + +The corresponding functions are: + +```cpp +connection.promised_read(buffer); +connection.promised_send(buffer); +``` + +For a TCP acceptor: + +```cpp +std::future connection = + acceptor.promised_accept(); + +auto client = connection.get(); +``` + +UDP sockets provide the same future-based interface: + +```cpp +std::future result = + socket.promised_send(endpoint, net::span(buffer)); + +size_t bytes_sent = result.get(); +``` + +For UDP reads, the future contains both the number of bytes received and information about the sender: + +```cpp +std::future>> result = + socket.promised_read(net::span(buffer)); + +auto [bytes_read, sender] = result.get(); +``` + +The future-based functions are available without requiring C++20 coroutines. + +### C++20 coroutines + +When compiling with C++20 or higher, Socketwrapper provides awaitable overloads for asynchronous networking operations. + +These overloads return a `net::op_awaitable` which can be used with `co_await`. + +For example: + +```cpp +net::task read_data(net::tcp_connection_v4& connection) +{ + char buffer[1024]; + + size_t bytes_read = + co_await connection.async_read(net::span(buffer)); + + co_return bytes_read; +} +``` + +The awaitable overloads are provided by the asynchronous networking functions: + +```cpp +connection.async_read(buffer); +connection.async_send(buffer); +acceptor.async_accept(); +``` + +For UDP sockets, the asynchronous write operation is named `async_write()`: + +```cpp +net::task send_data( + net::udp_socket_v4& socket, + const net::endpoint& endpoint) +{ + char buffer[] = "Hello"; + + size_t bytes_sent = + co_await socket.async_write(endpoint, net::span(buffer)); + + co_return bytes_sent; +} +``` + +### `task` + +`net::task` is a lazily evaluated coroutine type provided by Socketwrapper. + +A coroutine returning a `net::task` does not begin execution until it is awaited or explicitly started. + +```cpp +net::task example(size_t input) +{ + co_return input * 2; +} + +net::task example_two() +{ + auto number = co_await example(5); +} +``` + +A `net::task` can be executed synchronously with `net::block_on()`: + +```cpp +size_t result = net::block_on(example(5)); +``` + +Alternatively, `net::spawn()` can be used to start the task immediately and obtain a `std::future`: + +```cpp +std::future result = net::spawn(example(5)); + +size_t value = result.get(); +``` + +Both `block_on()` and `spawn()` are available when compiling with C++20 or higher. ## Class Documentation: + All of the following classes and enum classes live in the namespace `net`. Socket/connection classes all are not copyable but moveable and templated to distinguish between IPv4 and IPv6 by using a enum class: + ```cpp enum class ip_version { @@ -46,322 +211,368 @@ Socket/connection classes all are not copyable but moveable and templated to dis ``` ### span ->#include "socketwrapper/span.hpp" (also included by all socket headers) + +> #include "socketwrapper/span.hpp" (also included by all socket headers) Non owning abstraction of a view to memory used to generalize the interface to the reading and sending methods of the socket classes. Can be created from all container types that can be represented by a pointer and a length. The interface of the span class is the same as for most std container classes (providing begin(), end(), front(), back(), empty(), size(), get(), data()). Methods: -- Constructor: - ```cpp - span(T* start, size_t length) noexcept; - - span(T* start, T* end) noexcept; - - span(T (&buffer)[S]) noexcept; - - // Create a span from a start and an end iterator. - span(ITER start, ITER end) noexcept; - - // Create a span from a class that provides the same interface as the std container classes. - span(CONTAINER&& con) noexcept; - ``` - + +* Constructor: + + ```cpp + span(T* start, size_t length) noexcept; + + span(T* start, T* end) noexcept; + + span(T (&buffer)[S]) noexcept; + + // Create a span from a start and an end iterator. + span(ITER start, ITER end) noexcept; + + // Create a span from a class that provides the same interface as the std container classes. + span(CONTAINER&& con) noexcept; + ``` + ### endpoint ->#include "socketwrapper/endpoint.hpp" + +> #include "socketwrapper/endpoint.hpp" Represents a endpoint of a IP/socket connection. Methods: -- Constructor: - ```cpp - // Constructs an endpoint from a string representation of a IP address, a port and the type of the connection (stream or datagram) - endpoint(std::string_view address_string, uint16_t port, socket_type connection_type); - - // Constructs an endpoint from a POSIX struct sockaddr_in - endpoint(const sockaddr_in& address); - - // Constructs an endpoint from a POSIX struct sockaddr_in6 - endpoint(const sockaddr_in6& address); - ``` -- Accessor: - ```cpp - // Returns the IP address of the represented endpoint in string representation - const std::string& get_addr_string() const; - - // Returns the port of the represented endpoint as a uint16_t - uint16_t get_port() const; - - // Returns information of the endpoint represented by a const reference to a POSIX struct sockaddr - const sockaddr& get_addr() const; - - // Returns information of the endpoint represented by a reference to a POSIX struct sockaddr - sockaddr& get_addr(); - ``` + +* Constructor: + + ```cpp + // Constructs an endpoint from a string representation of a IP address, a port and the type of the connection (stream or datagram) + endpoint(std::string_view address_string, uint16_t port, socket_type connection_type); + + // Constructs an endpoint from a POSIX struct sockaddr_in + endpoint(const sockaddr_in& address); + + // Constructs an endpoint from a POSIX struct sockaddr_in6 + endpoint(const sockaddr_in6& address); + ``` +* Accessor: + + ```cpp + // Returns the IP address of the represented endpoint in string representation + const std::string& get_addr_string() const; + + // Returns the port of the represented endpoint as a uint16_t + uint16_t get_port() const; + + // Returns information of the endpoint represented by a const reference to a POSIX struct sockaddr + const sockaddr& get_addr() const; + + // Returns information of the endpoint represented by a reference to a POSIX struct sockaddr + sockaddr& get_addr(); + ``` ### option -This class is used in the methods ```base_socket::get_option```, ```base_socket::get_option_value``` and ```base_socket::set_option``` to set and get socket options. -It is included implicitly with the class ```base_socket```. + +This class is used in the methods `base_socket::get_option`, `base_socket::get_option_value` and `base_socket::set_option` to set and get socket options. +It is included implicitly with the class `base_socket`. Methods: -- Constructors: - ```cpp - option() = default; - - option(int value); - ``` -- Accessors/Modifiers: - ```cpp - size_t size() const; - - int name() const; - - option_level level() const; - - int level_native() const; - - const int* value() const; - - int* value(); - ``` + +* Constructors: + + ```cpp + option() = default; + + option(int value); + ``` +* Accessors/Modifiers: + + ```cpp + size_t size() const; + + int name() const; + + option_level level() const; + + int level_native() const; + + const int* value() const; + + int* value(); + ``` Valid template specializations for parameter T are: + * int * bool * linger * sockaddr ### base_socket -This class is implicitly included with every socket class that inherits from the class ```base_socket```. + +This class is implicitly included with every socket class that inherits from the class `base_socket`. Represents the basic functionalities of the native socket handle. The other high-level socket abstractions are all dervived from this class. Methods: -- Set/get socket options: - ```cpp - // Set a socket option where the option is represented by a valid template specialization of net::option - template ::value, bool>> - void set_option(OPTION_TYPE&& opt_val); - - // Get a current socket option where the option type needs to be a valid template specialization of net::option - template ::value, bool>> - OPTION_TYPE get_option() const - - // Get the current value of a socket option where the option type needs to be a valid template specialization of net::option - template ::value, bool>> - typename OPTION_TYPE::value_type get_option_value() const - ``` -- Other: - ```cpp - // Get the underlying socket handle - int get() const; - - // Get the ip version of the represented socket - ip_version family() const; - ``` + +* Set/get socket options: + + ```cpp + // Set a socket option where the option is represented by a valid template specialization of net::option + template ::value, bool>> + void set_option(OPTION_TYPE&& opt_val); + + // Get a current socket option where the option type needs to be a valid template specialization of net::option + template ::value, bool>> + OPTION_TYPE get_option() const + + // Get the current value of a socket option where the option type needs to be a valid template specialization of net::option + template ::value, bool>> + typename OPTION_TYPE::value_type get_option_value() const + ``` +* Other: + + ```cpp + // Get the underlying socket handle + int get() const; + + // Get the ip version of the represented socket + ip_version family() const; + ``` ### tcp_connection : public base_socket ->#include "socketwrapper/tcp.hpp" + +> #include "socketwrapper/tcp.hpp" Represents a TCP connection that can either be constructed with the IP address and port of the remote host or by a `tcp_acceptor`s accept method. Methods: -- Constructor: - ```cpp - // Default constructor of a not connected tcp connection - tcp_connection(); - - // Construct a tcp connection from a net::endpoint - tcp_connection(const endpoint& endpoint); - ``` -- Config: - ```cpp - // Connect a default constructed socket to a given endpoint - void connect(const endpoint& endpoint); - ``` -- Reading: - ```cpp - // Read as much bytes as fit into buffer and block until the read operation finishes. - size_t read(net::spanbuffer) const; - - // Read as much bytes as fit into buffer and block until the read operation finishes or the delay is over. - size_t read(net::span buffer, const std::chrono::duration& delay) const; - - // Immediately return and call the callback function after there is data available. - void async_read(net::span buffer, CALLBACK_TYPE&& callback) const; - - // Immediately returns an awaitable that can be co_awaited in a C++20 coroutine - // Only available when compiling with C++20 or higher - net::op_awaitable> async_read(net::span buffer) const; - - // Immediately return and get a future to get the number of elements received at a later timepoint - std::future promised_read(net::span buffer) const; - ``` -- Sending: - ```cpp - // Sends all data that is stored in the given buffer and blocks until all data is sent. - size_t send(net::span buffer) const; - - // Immediately returns and invokes the callback after all in the given buffer is send. Caller is responsible to keep the data the span shows alive. - void async_send(net::span buffer, CALLBACK_TYPE&& callback) const; - - // Immediately returns an awaitable that can be co_awaited in a C++20 coroutine - // Only available when compiling with C++20 or higher - net::op_awaitable> async_send(net::span buffer) const; - - // Immediately return and get a future to get the number of elements written at a later point in time - std::future promised_send(net::span buffer) const; - ``` -- Shorthand identifier: - ```cpp - using tcp_connection_v4 = tcp_connection; - using tcp_connection_v6 = tcp_connection; - ``` - + +* Constructor: + + ```cpp + // Default constructor of a not connected tcp connection + tcp_connection(); + + // Construct a tcp connection from a net::endpoint + tcp_connection(const endpoint& endpoint); + ``` +* Config: + + ```cpp + // Connect a default constructed socket to a given endpoint + void connect(const endpoint& endpoint); + ``` +* Reading: + + ```cpp + // Read as much bytes as fit into buffer and block until the read operation finishes. + size_t read(net::spanbuffer) const; + + // Read as much bytes as fit into buffer and block until the read operation finishes or the delay is over. + size_t read(net::span buffer, const std::chrono::duration& delay) const; + + // Immediately return and call the callback function after there is data available. + void async_read(net::span buffer, CALLBACK_TYPE&& callback) const; + + // Immediately returns an awaitable that can be co_awaited in a C++20 coroutine + // Only available when compiling with C++20 or higher + net::op_awaitable> async_read(net::span buffer) const; + + // Immediately return and get a future to get the number of elements received at a later timepoint + std::future promised_read(net::span buffer) const; + ``` +* Sending: + + ```cpp + // Sends all data that is stored in the given buffer and blocks until all data is sent. + size_t send(net::span buffer) const; + + // Immediately returns and invokes the callback after all in the given buffer is send. Caller is responsible to keep the data the span shows alive. + void async_send(net::span buffer, CALLBACK_TYPE&& callback) const; + + // Immediately returns an awaitable that can be co_awaited in a C++20 coroutine + // Only available when compiling with C++20 or higher + net::op_awaitable> async_send(net::span buffer) const; + + // Immediately return and get a future to get the number of elements written at a later point in time + std::future promised_send(net::span buffer) const; + ``` +* Shorthand identifier: + + ```cpp + using tcp_connection_v4 = tcp_connection; + using tcp_connection_v6 = tcp_connection; + ``` + ### tcp_acceptor public base_socket ->#include "socketwrapper/tcp.hpp" + +> #include "socketwrapper/tcp.hpp" Represents a listening TCP socket that accepts incoming connections. Returns a `tcp_connection` for each accepted connection. Methods: -- Constructor: - ```cpp - // Default constructor of a non-bound tcp acceptor - tcp_acceptor(); - - // Immediately creates a socket that listens on the given address and port with a connection backlog of `backlog` - tcp_acceptor(const endpoint& endpoint, const size_t backlog = 5); - ``` -- Config: - ```cpp - // Bind a non-bound acceptor to a internal endpoint and set the socket in listening state - void activate(const endpoint& endpoint, const size_t backlog = 5); - ``` -- Accepting: - ```cpp - // Blocks until a connection request is available and returns a constructed and connected tcp_connection instance - tcp_connection accept() const; - - // Blocks until a connection request is available or the delay is over and returns a constructed and connected tcp_connection instance or std::nullopt(if no connection was established) - std::optional> accept(const std::chrono::duration& delay) const; - - // Immediately returns and invokes the callback when a new connection is established - void async_accept(CALLBACK_TYPE&& callback) const; - - // Immediately returns an awaitable that can be co_awaited in a C++20 coroutine - // Only available when compiling with C++20 or higher - net::op_awaitable, net::tcp_acceptor::stream_accept_operation> async_accept() const; - - // Immediately return and get a future to access the accepted socket at a later point in time - std::future> promised_accept() const; - ``` -- Shorthand identifier: - ```cpp - using tcp_acceptor_v4 = tcp_acceptor; - using tcp_acceptor_v6 = tcp_acceptor; - ``` - + +* Constructor: + + ```cpp + // Default constructor of a non-bound tcp acceptor + tcp_acceptor(); + + // Immediately creates a socket that listens on the given address and port with a connection backlog of `backlog` + tcp_acceptor(const endpoint& endpoint, const size_t backlog = 5); + ``` +* Config: + + ```cpp + // Bind a non-bound acceptor to a internal endpoint and set the socket in listening state + void activate(const endpoint& endpoint, const size_t backlog = 5); + ``` +* Accepting: + + ```cpp + // Blocks until a connection request is available and returns a constructed and connected tcp_connection instance + tcp_connection accept() const; + + // Blocks until a connection request is available or the delay is over and returns a constructed and connected tcp_connection instance or std::nullopt(if no connection was established) + std::optional> accept(const std::chrono::duration& delay) const; + + // Immediately returns and invokes the callback when a new connection is established + void async_accept(CALLBACK_TYPE&& callback) const; + + // Immediately returns an awaitable that can be co_awaited in a C++20 coroutine + // Only available when compiling with C++20 or higher + net::op_awaitable, net::tcp_acceptor::stream_accept_operation> async_accept() const; + + // Immediately return and get a future to access the accepted socket at a later point in time + std::future> promised_accept() const; + ``` +* Shorthand identifier: + + ```cpp + using tcp_acceptor_v4 = tcp_acceptor; + using tcp_acceptor_v6 = tcp_acceptor; + ``` + ### tls_connection : public tcp_connection ->#include "socketwrapper/tls.hpp" + +> #include "socketwrapper/tls.hpp" Represents a TLS encrypted TCP connection that can either be constructed with the IP address and port of the remote host or by a `tcp_acceptor`s accept method. Methods: -- Constructor: - ```cpp - // Construct a non connected tls connection - tls_connection(std::string_view cert_path, std::string_view key_path); - - // Construct a tls connection from an endpoint and immediately connect it - tls_connection(std::string_view cert_path, std::string_view key_path, const endpoint& endpoint); - ``` -- Reading: - Same interface as `tcp_connection` -- Writing: - Same interface as `tcp_connection` -- Shorthand identifier: - ```cpp - using tls_connection_v4 = tls_connection; - using tls_connection_v6 = tls_connection; - ``` - + +* Constructor: + + ```cpp + // Construct a non connected tls connection + tls_connection(std::string_view cert_path, std::string_view key_path); + + // Construct a tls connection from an endpoint and immediately connect it + tls_connection(std::string_view cert_path, std::string_view key_path, const endpoint& endpoint); + ``` +* Reading: + Same interface as `tcp_connection` +* Writing: + Same interface as `tcp_connection` +* Shorthand identifier: + + ```cpp + using tls_connection_v4 = tls_connection; + using tls_connection_v6 = tls_connection; + ``` + ### tls_acceptor : public tcp_acceptor ->#include "socketwrapper/tls.hpp" + +> #include "socketwrapper/tls.hpp" + Represents a listening TCP socket with TLS encryption that accepts incoming connections. Returns a `tcp_connection` for each accepted connection. Methods: -- Constructor: - ```cpp - // Construct a non-bound tls_acceptor - tls_acceptor(std::string_view cert_path, std::string_view key_path); - - // Construct a tls acceptor from an endpoint and set it into listening state - tls_acceptor(std::string_view cert_path, std::string_view key_path, const endpoint& endpoint); - ``` -- Accepting: - Same interface as `tcp_acceptor` -- Shorthand identifier: - ```cpp - using tls_acceptor_v4 = tls_acceptor; - using tls_acceptor_v6 = tls_acceptor; - ``` + +* Constructor: + + ```cpp + // Construct a non-bound tls_acceptor + tls_acceptor(std::string_view cert_path, std::string_view key_path); + + // Construct a tls acceptor from an endpoint and set it into listening state + tls_acceptor(std::string_view cert_path, std::string_view key_path, const endpoint& endpoint); + ``` +* Accepting: + Same interface as `tcp_acceptor` +* Shorthand identifier: + + ```cpp + using tls_acceptor_v4 = tls_acceptor; + using tls_acceptor_v6 = tls_acceptor; + ``` ### udp_socket : public base_socket ->#include "socketwrapper/udp.hpp" + +> #include "socketwrapper/udp.hpp" Represents an UDP socket that can either be in "server" or "client" position. Methods: -- Constructor: - ```cpp - // Creates a non-bound UDP socket that is ready to send data but can not receive data. - udp_socket(); - - // Creates a UDP socket that is bound to a given endpoint so it can send and receive data directly after construction - udp_socket(const endpoint& endpoint); - ``` -- Config: - ```cpp - // Bind a non-bound udp socket to a given endpoint so that it is able to receive data afterwards - void bind(const endpoint& endpoint); - ``` -- Reading: - ```cpp - // Block until data is read into the given buffer. Reads max the amount of elements that fits into the buffer. - std::pair> read(span buffer) const; - - // Block until data is read into the given buffer or the delay is over. Reads max the amount of elements that fits into the buffer. - std::pair>> read(span buffer, const std::chrono::duration& delay) const; - - // Immediately return and invoke the callback when data is read into the buffer. Caller is responsible to keep the underlying buffer alive. - void async_read(span buffer, CALLBACK_TYPE&& callback) const; - - // Immediately returns an awaitable that can be co_awaited in a C++20 coroutine - // Only available when compiling with C++20 or higher - net::op_awaitable>>, net::udp_socket::dgram_read_operation> async_read(span buffer) const; - - // Immediately return and get a future to get the number of elements read and the connection info of the sender at a later point in time - std::future>> promised_read(span buffer) const; - ``` -- Writing: - ```cpp - // Send all data in the given buffer to a remote endpoint. - size_t send(const endpoint& endpoint_to, span buffer) const; - - // Immediately return and invoke the callback after the data is sent to a remote represented by the given address and port parameter. - void async_send(const endpoint& endpoint_to, span buffer, CALLBACK_TYPE&& callback) const; - - // Immediately returns an awaitable that can be co_awaited in a C++20 coroutine - // Only available when compiling with C++20 or higher - net::op_awaitable> async_write(const endpoint& endpoint_to, span buffer) const; - - // Immediately return and get a future to get the number of elements written at a later point in time - std::future promised_send(const endpoint& endpoint_to, span buffer) const; - ``` -- Shorthand identifier: - ```cpp - using udp_socket_v4 = udp_socket; - using udp_socket_v6 = udp_socket; - ``` + +* Constructor: + + ```cpp + // Creates a non-bound UDP socket that is ready to send data but can not receive data. + udp_socket(); + + // Creates a UDP socket that is bound to a given endpoint so it can send and receive data directly after construction + udp_socket(const endpoint& endpoint); + ``` +* Config: + + ```cpp + // Bind a non-bound udp socket to a given endpoint so that it is able to receive data afterwards + void bind(const endpoint& endpoint); + ``` +* Reading: + + ```cpp + // Block until data is read into the given buffer. Reads max the amount of elements that fits into the buffer. + std::pair> read(span buffer) const; + + // Block until data is read into the given buffer or the delay is over. Reads max the amount of elements that fits into the buffer. + std::pair>> read(span buffer, const std::chrono::duration& delay) const; + + // Immediately return and invoke the callback when data is read into the buffer. Caller is responsible to keep the underlying buffer alive. + void async_read(span buffer, CALLBACK_TYPE&& callback) const; + + // Immediately returns an awaitable that can be co_awaited in a C++20 coroutine + // Only available when compiling with C++20 or higher + net::op_awaitable>>, net::udp_socket::dgram_read_operation> async_read(span buffer) const; + + // Immediately return and get a future to get the number of elements read and the connection info of the sender at a later point in time + std::future>> promised_read(span buffer) const; + ``` +* Writing: + + ```cpp + // Send all data in the given buffer to a remote endpoint. + size_t send(const endpoint& endpoint_to, span buffer) const; + + // Immediately return and invoke the callback after the data is sent to a remote represented by the given address and port parameter. + void async_send(const endpoint& endpoint_to, span buffer, CALLBACK_TYPE&& callback) const; + + // Immediately returns an awaitable that can be co_awaited in a C++20 coroutine + // Only available when compiling with C++20 or higher + net::op_awaitable> async_write(const endpoint& endpoint_to, span buffer) const; + + // Immediately return and get a future to get the number of elements written at a later point in time + std::future promised_send(const endpoint& endpoint_to, span buffer) const; + ``` +* Shorthand identifier: + + ```cpp + using udp_socket_v4 = udp_socket; + using udp_socket_v6 = udp_socket; + ``` ### task ->#include "socketwrapper/task.hpp" + +> #include "socketwrapper/task.hpp" Representation of a lazily evaluated coroutine without any special functionality that holds a `std::coroutine_handle` of the parent coroutine frame. It defines a `promise_type` and implements the `awaitable` which allows awaiting this type. @@ -371,6 +582,7 @@ This is a helper class to give a user a coroutine class to utilize the networkin This class is only available when compiling with C++20 or higher Example of a coroutine that returns `net::task`: + ```cpp net::task example(size_t input) { @@ -384,48 +596,54 @@ net::task example_two() ``` ## Utility Functions: ->#include "socketwrapper/utility.hpp" + +> #include "socketwrapper/utility.hpp" All of the following functions live in the namespace `net` -- Change byte order: - ```cpp - // Change byte order from little-endian to big-endian - template - inline constexpr T to_big_endian(T little); +* Change byte order: - // Change byte order from big-endian to little-endian - template - inline constexpr T to_little_endian(T big); + ```cpp + // Change byte order from little-endian to big-endian + template + inline constexpr T to_big_endian(T little); - // Change byteorder from host byte order to network byte order if they differ - template - inline constexpr T host_to_network(T in); + // Change byte order from big-endian to little-endian + template + inline constexpr T to_little_endian(T big); - // Change byteorder from network byte order to host byte order if they differ - template - inline constexpr T network_to_host(T in); - ``` + // Change byteorder from host byte order to network byte order if they differ + template + inline constexpr T host_to_network(T in); + + // Change byteorder from network byte order to host byte order if they differ + template + inline constexpr T network_to_host(T in); + ``` ## Runtime helper functions: + This functions are implicitly included with every socket header file. -- Run the asynchronous context until all callbacks are handled: - ```cpp - // Blocks until all registered async operations are handled and all completion handlers finished execution. - void async_run(); - ``` -- Block the current thread until the coroutine represented by the `net::task` parameter is completely evaluated. -Only available when compiling with C++20 or higher - ```cpp - template - return_type block_on(net::task awaitable_task); - ``` -- Convert a lazily evaluated coroutine that is represented by `net::task` into an eagerly evaluated future. -By performing this conversion the task starts execution right away until it reaches its first suspension point while -the task itself would normally be suspended right away and only starts execution if it is awaited. -Only available when compiling with C++20 or higher - ```cpp - template - std::future spawn(net::task awaitable_task); - ``` +* Run the asynchronous context until all callbacks are handled: + + ```cpp + // Blocks until all registered async operations are handled and all completion handlers finished execution. + void async_run(); + ``` +* Block the current thread until the coroutine represented by the `net::task` parameter is completely evaluated. + Only available when compiling with C++20 or higher + + ```cpp + template + return_type block_on(net::task awaitable_task); + ``` +* Convert a lazily evaluated coroutine that is represented by `net::task` into an eagerly evaluated future. + By performing this conversion the task starts execution right away until it reaches its first suspension point while + the task itself would normally be suspended right away and only starts execution if it is awaited. + Only available when compiling with C++20 or higher + + ```cpp + template + std::future spawn(net::task awaitable_task); + ```