#include #include "socket-cpp/acceptor.h" using namespace std; using namespace osdev::components::socket-cpp; acceptor acceptor::create(int domain) { acceptor acc(create_handle(domain)); if (!acc) acc.clear(get_last_error()); return acc; } // -------------------------------------------------------------------------- // This attempts to open the acceptor, bind to the requested address, and // start listening. On any error it will be sure to leave the underlying // socket in an unopened/invalid state. // If the acceptor appears to already be opened, this will quietly succeed // without doing anything. bool acceptor::open(const sock_address& addr, int queSize /*=DFLT_QUE_SIZE*/, bool reuseSock /*=true*/) { // TODO: What to do if we are open but bound to a different address? if (is_open()) return true; sa_family_t domain = addr.family(); socket_t h = create_handle(domain); if (!check_socket_bool(h)) return false; reset(h); #if defined(_WIN32) const int REUSE = SO_REUSEADDR; #else const int REUSE = SO_REUSEPORT; #endif if (reuseSock && (domain == AF_INET || domain == AF_INET6)) { int reuse = 1; if (!set_option(SOL_SOCKET, REUSE, reuse)) return close_on_err(); } if (!bind(addr) || !listen(queSize)) return close_on_err(); return true; } // -------------------------------------------------------------------------- stream_socket acceptor::accept(sock_address* clientAddr /*=nullptr*/) { sockaddr* p = clientAddr ? clientAddr->sockaddr_ptr() : nullptr; socklen_t len = clientAddr ? clientAddr->size() : 0; socket_t s = check_socket(::accept(handle(), p, clientAddr ? &len : nullptr)); return stream_socket(s); }