#pragma once #include "address.hpp" #include #include #include #ifdef _WIN32 using send_size = int; using sent_size = int; #define GET_SOCKET_ERROR() (WSAGetLastError()) #define poll WSAPoll #define SERR(x) (WSA##x) #define SHUT_RDWR SD_BOTH #else using SOCKET = int; using send_size = size_t; using sent_size = ssize_t; #define INVALID_SOCKET (SOCKET)(~0) #define SOCKET_ERROR (-1) #define GET_SOCKET_ERROR() (errno) #define closesocket close #define SERR(x) (x) #endif namespace network { class socket { public: socket() = default; socket(SOCKET s); socket(int af, int type, int protocol); virtual ~socket(); socket(const socket& obj) = delete; socket& operator=(const socket& obj) = delete; socket(socket&& obj) noexcept; socket& operator=(socket&& obj) noexcept; operator bool() const; bool is_valid() const; bool bind(const address& target); bool listen(int backlog); SOCKET accept(address& address); bool set_blocking(bool blocking); static bool set_blocking(SOCKET s, bool blocking); static constexpr bool socket_is_ready = true; bool sleep(std::chrono::milliseconds timeout, bool in_poll = true) const; bool sleep_until(std::chrono::high_resolution_clock::time_point time_point, bool in_poll = true) const; SOCKET get_socket() const; uint16_t get_port() const; std::optional
get_name() const; int get_address_family() const; bool is_ready(bool in_poll) const; bool is_listening() const; static bool sleep_sockets(const std::span& sockets, std::chrono::milliseconds timeout, bool in_poll); static bool sleep_sockets_until(const std::span& sockets, std::chrono::high_resolution_clock::time_point time_point, bool in_poll); static bool is_socket_ready(SOCKET s, bool in_poll); void close(); private: SOCKET socket_ = INVALID_SOCKET; bool listening_{}; }; }