#include #include #include #include #include struct WSA { WSADATA wsa; explicit WSA(WORD version = MAKEWORD(2, 2)) { int result = WSAStartup(version, &wsa); if (result) throw result; } ~WSA() noexcept { WSACleanup(); } }; struct Buffer { std::vector data; explicit Buffer(int len): data(len, 0) {} char* get() noexcept { return data.data(); } const char* get() const noexcept { return data.data(); } int len() const noexcept { return data.size(); } }; struct Socket { enum AddrAction { NO_ACTION, CONNECT, BIND, }; SOCKET s; struct sockaddr addr; explicit Socket(SOCKET init = INVALID_SOCKET) noexcept: s(init) {} ~Socket() noexcept { closesocket(s); } operator SOCKET() const noexcept { return s; } explicit operator bool() const noexcept { return is_valid(); } bool is_valid() const noexcept { return s != INVALID_SOCKET; } void from_addrinfo(const struct addrinfo &info, AddrAction action = NO_ACTION); Socket accept_client() const noexcept { return Socket(accept(s, NULL, NULL)); } void stop_send() const { int result = shutdown(s, SD_SEND); if (result == SOCKET_ERROR) throw result; } int send_data(const Buffer &data) const noexcept { return send(s, data.get(), data.len(), 0); } int recv_data(Buffer &data) const noexcept { return recv(s, data.get(), data.len(), 0); } };