The tcp_acceptor represents the traditional server side of a connection. It will listen for connections on an inbound port. Deconstruction or moving the tcp_acceptor while in use results in undefined behavior.


Example
async_function<>
your_class::run_acceptor()
{
    tcp_acceptor acceptor(engine_);
    // listen for IPv4 on port 8080 with a maximum backlog of 10
    // See bind(2) and listen(2) for more details...
    if (acceptor.listen(AF_INET, 8080, 10))
    {
        while (true)
        {
            std::optional<tcp_stream> stream_opt = co_await acceptor.accept();

            if (stream_opt)
            {
                std::cout << "Got a connection\n";
            }
            else
            {
                std::cout << "Got a error" << acceptor.last_error() << "\n";
            }
        }
    }
}

class zab::tcp_acceptor : public zab::network_operation

This class allows for asynchronous server based socket operations.

The methods of the class are essentially asynchronous equivalents to socket(2), bind(2), listen(2) and accept(2)

Public Functions

tcp_acceptor() = default

Constructs a new instance in an empty state.

        If this constructor is used, use of `listen` and `accept`,
        will result in undefined behavior until `register_engine`
        is called with a valid engine.

tcp_acceptor(engine *_engine)

Constructs a new instance in an empty state but with an engine registered.

Parameters

_engine – The engine to register.

tcp_acceptor(const tcp_acceptor&) = delete

Copy constructor is deleted.

tcp_acceptor(tcp_acceptor &&_move) = default

Moves a tcp_acceptor leaving it in an empty state and no engine registered.

Parameters

_move – The tcp_acceptor to move.

tcp_acceptor &operator=(tcp_acceptor &&_move) = default

Moves a tcp_acceptor leaving it in an empty state and with no engine.

Parameters

_move – The acceptor to move.

Returns

The result of the assignment.

~tcp_acceptor() = default

Destroys the acceptor, closing its socket.

bool listen(int _family, std::uint16_t _port, int _backlog) noexcept

Start listening to connections on a newly created socket.

This function is essentially creates a new socket using ::socket(), sets SO_REUSEADDR, then calls ::bind() and ::listen().

Parameters
  • _family – AF_INET or AF_INET6 for ipv4 and ipv6 respectively.

  • _port – Which port to listen on.

  • _backlog – The maximum amount of pending connections to hold.

Returns

true If started successfully.

Returns

false If an error occurs. last_error() is set.

template<MemoryType DataType = std::byte>
inline auto accept(struct sockaddr *_address, socklen_t *_length, int _flags = SOCK_CLOEXEC) noexcept

Attempts to accept a connection.

This function always suspends.

     This function is cancelable using the `cancel()` function.

     The function calls `::accept()` on the socket with parameters given.
     The socket produced from this call is used to create a tcp_stream.

Template Parameters

DataType – The type of memory the produced tcp_stream will use.

Parameters
  • _address – A ptr to the sockaddr like struct to be filled out.

  • _length – A ptr to the socklen_t the indicates the memory length of _address.

  • _flags – The flags to apply to the accept call. The default is SOCK_CLOEXEC. See ::accept4() @co_return tcp_stream<DataType> if no error occurs, or std::nullopt.

Friends

friend void swap(tcp_acceptor &_first, tcp_acceptor &_second) noexcept

Swap two acceptors.

Parameters
  • _first – The first

  • _second – The second