Chops Net IP
|
The basic_io_interface
class template provides access to an underlying network IO handler (TCP or UDP IO handler), primarily for calling the start_io
, stop_io
, and make_io_output
methods.
More...
#include <basic_io_interface.hpp>
Public Types | |
using | endpoint_type = typename IOT::endpoint_type |
Public Member Functions | |
basic_io_interface ()=default | |
Default construct a basic_io_interface . | |
basic_io_interface (const basic_io_interface &)=default | |
basic_io_interface (basic_io_interface &&)=default | |
basic_io_interface< IOT > & | operator= (const basic_io_interface &)=default |
basic_io_interface< IOT > & | operator= (basic_io_interface &&)=default |
basic_io_interface (std::weak_ptr< IOT > p) noexcept | |
Construct with a shared weak pointer to an internal IO handler, this is an internal constructor only and not to be used by application code. | |
bool | is_valid () const noexcept |
Query whether an IO handler is associated with this object. | |
auto | make_io_output () const -> nonstd::expected< basic_io_output< IOT >, std::error_code > |
Make a basic_io_output object from the associated IO handler. | |
auto | is_io_started () const -> nonstd::expected< bool, std::error_code > |
Query whether an IO handler is in a started state or not. | |
template<typename F > | |
auto | visit_socket (F &&func) -> nonstd::expected< void, std::error_code > |
Provide an application supplied function object which will be called with a reference to the associated IO handler socket. | |
template<typename MH , typename MF > | |
auto | start_io (std::size_t header_size, MH &&msg_handler, MF &&msg_frame) -> nonstd::expected< void, std::error_code > |
Enable IO processing for the associated network IO handler with message frame logic. | |
template<typename MH > | |
auto | start_io (std::size_t header_size, MH &&msg_handler, hdr_decoder_func func) -> nonstd::expected< void, std::error_code > |
Enable IO processing for the associated network IO handler with simple variable length message frame logic. | |
template<typename MH > | |
auto | start_io (std::string_view delimiter, MH &&msg_handler) -> nonstd::expected< void, std::error_code > |
Enable IO processing for the associated network IO handler with delimeter logic. | |
template<typename MH > | |
auto | start_io (std::size_t read_size, MH &&msg_handler) -> nonstd::expected< void, std::error_code > |
Enable IO processing for the associated network IO handler with fixed or maximum buffer size logic. | |
template<typename MH > | |
auto | start_io (const endpoint_type &endp, std::size_t max_size, MH &&msg_handler) -> nonstd::expected< void, std::error_code > |
Enable IO processing for the associated network IO handler with a maximum buffer size and a default destination endpoint. | |
auto | start_io () -> nonstd::expected< void, std::error_code > |
Enable IO processing for the associated network IO handler with no incoming message handling. | |
auto | start_io (const endpoint_type &endp) -> nonstd::expected< void, std::error_code > |
Enable IO processing for the associated network IO handler with no incoming message handling, but with a default destination endpoint. | |
auto | stop_io () -> nonstd::expected< void, std::error_code > |
Stop IO processing and close the associated network IO handler. | |
bool | operator== (const basic_io_interface< IOT > &rhs) const noexcept |
Compare two basic_io_interface objects for equality. | |
bool | operator< (const basic_io_interface< IOT > &rhs) const noexcept |
Compare two basic_io_interface objects for ordering purposes. | |
const void * | get_ptr () const noexcept |
Return a raw pointer to an associated IO handler. | |
Related Symbols | |
(Note that these are not member symbols.) | |
using | tcp_io_interface = basic_io_interface<tcp_io> |
Using declaration for a TCP based basic_io_interface type. | |
using | udp_io_interface = basic_io_interface<udp_io> |
Using declaration for a UDP based basic_io_interface type. | |
using | hdr_decoder_func = std::size_t (*)(const std::byte* ptr, std::size_t sz) |
Signature for a variable length message header decoder function, used in one of the basic_io_interface start_io methods. | |
The basic_io_interface
class template provides access to an underlying network IO handler (TCP or UDP IO handler), primarily for calling the start_io
, stop_io
, and make_io_output
methods.
The basic_io_interface
class provides the primary application interface to start network IO processing, whether TCP or UDP. This class provides methods to start IO processing (i.e. start read processing and enable write processing), stop IO processing (if needed, typically doesn't need to be directly called), and access the IO handler socket (e.g. to retrieve or modify socket options). It also provides a method to create a basic_io_output
object for sending data.
The start_io
and stop_io
methods are not a data flow toggle. In other words, once start_io
is called, no other start_io
methods can be called. If stop_io
is called, connection teardown (or socket close) is initiated, and start_io
will not be possible.
Calling stop_io
is not necessary and is only needed if an application needs to close a connection or socket directly and not through other means (e.g. a net_entity
close
or a connection termination or a message handler false
return).
This class is a lightweight value class, allowing basic_io_interface
objects to be copied and used in multiple places in an application, all of them accessing the same network IO handler. Internally, a std::weak
pointer is used to link the basic_io_interface
object with a network IO handler.
A basic_io_interface
object is provided for application use through a state change function object callback. This occurs when a net_entity
creates the underlying network IO handler, or the network IO handler is being closed and destructed. The net_entity
class documentation provides more detail.
A basic_io_interface
object is either associated with a network IO handler (i.e. the std::weak
pointer is good), or not. The is_valid
method queries if the association is present. Note that even if the std::weak_pointer
is valid, the network IO handler might be in the process of closing or being destructed.
Applications can default construct a basic_io_interface
object, but it is not useful until a valid basic_io_interface
object is assigned to it (typically this would be performed through the state change function object callback).
A basic_io_output
object can be created from a basic_io_interface
, allowing the sending of data to the underlying network IO handler.
The underlying network IO handler socket can be accessed through the visit_socket
method. This allows socket options to be queried and set (or other useful socket methods to be called).
Appropriate comparison operators are provided to allow basic_io_interface
objects to be used in associative or sequence containers.
All basic_io_interface
methods can be called concurrently from multiple threads, but calling stop_io
at the same time as start_io
from multiple threads may result in undesired application behavior.
Error handling is provided by returning a nonstd::expected
object on most methods.
|
default |
Default construct a basic_io_interface
.
A basic_io_interface
is not useful until an active basic_io_interface
is assigned into it.
|
inlinenoexcept |
Return a raw pointer to an associated IO handler.
This method provides a raw pointer to an associated IO handler (or nullptr
). This value can be used for logging or associative container lookup purposes. In particular, this value can be used to correlate multiple error messages from the same IO handler instantiation.
nullptr
.
|
inline |
Query whether an IO handler is in a started state or not.
nonstd::expected
- bool
on success, specifying whether start_io
on the IO handler has been called (if false
, the IO handler has not been started or is in a stopped state); on error (if no associated IO handler), a std::error_code
is returned.
|
inlinenoexcept |
Query whether an IO handler is associated with this object.
If true
, an IO handler (e.g. TCP or UDP IO handler) is associated. However, the IO handler may be closing down and may not allow further operations.
true
if associated with an IO handler.
|
inline |
Make a basic_io_output
object from the associated IO handler.
A basic_io_output
object is used for sending data. A basic_io_output
object will be created even if start_io
has not been called, and attempting to send data before start_io
is called will result in discarded data.
nonstd::expected
- basic_io_output
on success, either a tcp_io_output
or udp_io_output
; on error (if no associated IO handler), a std::error_code
is returned.
|
inlinenoexcept |
Compare two basic_io_interface
objects for ordering purposes.
The comparison is made through the std::shared_ptr
operator<
method. All invalid basic_io_interface
objects are less than valid ones. When both are valid, the address ordering is returned.
|
inlinenoexcept |
Compare two basic_io_interface
objects for equality.
The comparison is made through the std::shared_ptr
operator==
method. The comparison is made on addresses if both basic_io_interface
objects are valid. If both basic_io_interface
objects are invalid, true
is returned (this implies that all invalid basic_io_interface
objects are equivalent). If one is valid and the other invalid, false
is returned.
|
inline |
Enable IO processing for the associated network IO handler with no incoming message handling.
This method is implemented for both TCP and UDP IO handlers.
This method is used to enable IO processing where only sends are needed (and no incoming message handling).
For TCP IO handlers, a read will be started, but no data processed (typically if the read completes it is due to an error condition). For UDP IO handlers, no reads are started.
nonstd::expected
- IO is started on success; on error, a std::error_code
is returned.
|
inline |
Enable IO processing for the associated network IO handler with no incoming message handling, but with a default destination endpoint.
This method is not implemented for TCP IO handlers (only for UDP IO handlers).
This allows the send
method without an endpoint to be called for UDP datagrams.
This method is used to enable IO processing where only sends are needed (and no incoming message handling).
endp | Default destination asio::ip::udp::endpoint . |
nonstd::expected
- IO is started on success; on error, a std::error_code
is returned.
|
inline |
Enable IO processing for the associated network IO handler with a maximum buffer size and a default destination endpoint.
This method is not implemented for TCP IO handlers (only for UDP IO handlers).
This allows the send
method without an endpoint to be called for UDP datagrams. The buffer will be sent to this destination endpoint.
The maximum size parameter is the same as the corresponding (without default destination endpoint) start_io
method.
Sends (writes) are enabled after this call.
endp | Default destination asio::ip::udp::endpoint . |
max_size | Maximum UDP datagram size. |
msg_handler | A message handler function object callback. The signature of the callback is: |
Returning false
from the message handler callback causes the UDP socket to be closed.
The message handler function object is moved if possible, otherwise it is copied. State data should be movable or copyable.
nonstd::expected
- IO is started on success; on error, a std::error_code
is returned.
|
inline |
Enable IO processing for the associated network IO handler with simple variable length message frame logic.
This method is not implemented for UDP IO handlers.
For TCP IO handlers, this starts read processing using a message handler function object callback and a simple variable length message header decoder function pointer. The message frame TCP processing is similar to the generalized message frame processing except that only simple variable length messages are supported. "Simple" means a fixed size header followed by one variable length body. The header must be able to be decoded with a simple function that returns the size (in bytes) of the body when given the full, fixed size header.
header_size | The initial read size (in bytes) of each incoming message, which should match the header size of the header decoder function. |
msg_handler | A message handler function object callback. The signature of the callback is: |
The buffer (first parameter) always references a full message. The basic_io_output
can be used for sending a reply. The endpoint is the remote endpoint that sent the data (not used in the send
method call, but may be useful for other purposes).
Returning false
from the message handler callback causes the connection to be closed.
The message handler function object is moved if possible, otherwise it is copied. State data should be movable or copyable.
func | A function that is of type hdr_decoder_func . |
nonstd::expected
- IO is started on success; on error, a std::error_code
is returned.
|
inline |
Enable IO processing for the associated network IO handler with message frame logic.
This method is not implemented for UDP IO handlers.
For TCP IO handlers, this starts read processing using a message handler function object callback and a message frame function object callback. Sends (writes) are enabled after this call.
This method is used for message frame based TCP processing. The logic is "read header, process data to determine size of rest of message, read rest of message". The message frame function object callback implements this logic. Once a complete message has been read, the message handler function object callback is invoked. There may be multiple iterations of calling the message frame function object before the message frame determines the complete message has been read.
header_size | The initial read size (in bytes) of each incoming message. |
msg_handler | A message handler function object callback. The signature of the callback is: |
The buffer (first parameter) always references a full message. The basic_io_output
can be used for sending a reply. The endpoint is the remote endpoint that sent the data (not used in the send
method call, but may be useful for other purposes).
Returning false
from the message handler callback causes the connection to be closed.
The message handler function object is moved if possible, otherwise it is copied. State data should be movable or copyable.
msg_frame | A message frame function object callback. The signature of the callback is: |
Each time the message frame callback is called by the Chops Net IP IO handler, the next chunk of incoming bytes is passed through the buffer parameter.
The callback returns the size of the next read, or zero as a notification that the complete message has been called and the message handler is to be invoked.
If there is non-trivial processing that is performed in the message frame object and the application wishes to keep any resulting state (typically to use within the message handler), one option is to design a single class that provides two operator function call overloads and use the same object (via std::ref
) for both the message handler and the message frame processing.
The message frame function object is moved if possible, otherwise it is copied. State data should be movable or copyable.
nonstd::expected
- IO is started on success; on error, a std::error_code
is returned.
|
inline |
Enable IO processing for the associated network IO handler with fixed or maximum buffer size logic.
This method is implemented for both TCP and UDP IO handlers.
For TCP IO handlers, this reads a fixed size message which is then passed to the message handler function object.
For UDP IO handlers, this specifies the maximum size of the datagram. For IPv4 this value can be up to 65,507 (for IPv6 the maximum is larger). If the incoming datagram is larger than the specified size, data will be truncated or lost.
Sends (writes) are enabled after this call.
read_size | Maximum UDP datagram size or TCP fixed read size. |
msg_handler | A message handler function object callback. The signature of the callback is: |
Returning false
from the message handler callback causes the TCP connection or UDP socket to be closed.
The message handler function object is moved if possible, otherwise it is copied. State data should be movable or copyable.
nonstd::expected
- IO is started on success; on error, a std::error_code
is returned.
|
inline |
Enable IO processing for the associated network IO handler with delimeter logic.
This method is not implemented for UDP IO handlers.
For TCP IO handlers, this starts read processing using a message handler function object callback. Sends (writes) are enabled after this call.
This method is used for delimiter based TCP processing (typically text based messages in TCP streams). The logic is "read data until the delimiter characters match" (which are usually "end-of-line" sequences). The message handler function object callback is then invoked.
delimiter | Delimiter characters denoting end of each message. |
msg_handler | A message handler function object callback. The signature of the callback is: |
The buffer points to the complete message including the delimiter sequence. The basic_io_output
can be used for sending a reply, and the endpoint is the remote endpoint that sent the data. Returning false
from the message handler callback causes the connection to be closed.
The message handler function object is moved if possible, otherwise it is copied. State data should be movable or copyable.
nonstd::expected
- IO is started on success; on error, a std::error_code
is returned.
|
inline |
Stop IO processing and close the associated network IO handler.
After this call, connection disconnect or socket close processing will occur, a state change function object callback will be invoked, and eventually the IO handler object will be destructed. start_io
cannot be called after stop_io
(in other words, start_io
followed by stop_io
followed by start_io
, etc is not supported).
For TCP entities (connectors and acceptors), the TCP connection will be taken down, but the entity will remain active. For UDP entities stop_io
is equivalent to calling stop
on the net_entity
.
nonstd::expected
- IO is started on success; on error, a std::error_code
is returned.
|
inline |
Provide an application supplied function object which will be called with a reference to the associated IO handler socket.
The function object must have one of the following signatures, depending on the IO handler type:
Within the function object socket options can be queried or modified.
nonstd::expected
- socket has been visited on success; on error (if no associated IO handler), a std::error_code
is returned.
|
related |
Signature for a variable length message header decoder function, used in one of the basic_io_interface
start_io
methods.
Given a buffer of std::bytes
corresponding to a header on a variable length message, decode the header and return the length in bytes of the message body. Specifically, only the size of the body should be returned, not the full message size (header plus body).
For example, a 14 byte header that contains a full message length would need to subtract 14 from the length before returning the value from this function.
This can only be a function pointer, not a function object. If state needs to be stored or more complex logic needed than can be provided by a simple function, then the start_io
that takes a full message frame function object should be used.
ptr | A pointer to the beginning of the variable len message header. |
sz | The size of the header buffer, in bytes, which should be the same for every call and match the parameter given to the basic_io_interface start_io call. |