#include "socket.hpp" #pragma comment(lib, "ws2_32.lib") WSA::WSA(WORD version) { int result = WSAStartup(version, &wsa); if (result) throw result; } WSA::~WSA() noexcept { WSACleanup(); } AddrInfoPtr::AddrInfoPtr() noexcept: info(nullptr) {} AddrInfoPtr::~AddrInfoPtr() noexcept { freeaddrinfo(info); } addrinfo** AddrInfoPtr::operator&() noexcept { return &info; } addrinfo& AddrInfoPtr::operator*() noexcept { return *info; } addrinfo* AddrInfoPtr::operator->() noexcept { return info; } const addrinfo& AddrInfoPtr::operator*() const noexcept { return *info; } AddrInfoPtr::operator addrinfo *() noexcept { return info; } AddrInfo::AddrInfo() noexcept { ZeroMemory(&info, sizeof(info)); } addrinfo* AddrInfo::operator->() noexcept { return &info; } addrinfo* AddrInfo::operator&() noexcept { return &info; } AddrInfo::operator const addrinfo&() const noexcept { return info; } AddrInfo::operator addrinfo&() noexcept { return info; } AddrInfoPtr AddrInfo::get_addrinfo(PCSTR node, PCSTR service) { AddrInfoPtr ptr; int result = getaddrinfo(node, service, &info, &ptr); if (result == SOCKET_ERROR) throw result; return ptr; } Socket::Socket(SOCKET init) noexcept: s(init) {} Socket::~Socket() noexcept { closesocket(s); } Socket::operator SOCKET() const noexcept { return s; } Socket::operator bool() const noexcept { return is_valid(); } bool Socket::is_valid() const noexcept { return s != INVALID_SOCKET; } void Socket::from_addrinfo(const addrinfo &info, AddrAction action) { s = socket(info.ai_family, info.ai_socktype, info.ai_protocol); if (s == INVALID_SOCKET) throw -1; int result = SOCKET_ERROR; switch (action) { case NO_ACTION: break; case CONNECT: result = connect(s, info.ai_addr, (int)info.ai_addrlen); if (result == SOCKET_ERROR) throw result; break; case BIND: result = bind(s, info.ai_addr, (int)info.ai_addrlen); if (result == SOCKET_ERROR) throw result; result = listen(s, SOMAXCONN); if (result == SOCKET_ERROR) throw result; break; } } Socket Socket::accept_client() const noexcept { return Socket(accept(s, NULL, NULL)); } void Socket::stop_send() const { int result = shutdown(s, SD_SEND); if (result == SOCKET_ERROR) throw result; } int Socket::send_data(const Buffer &data) const { return send(s, data.get(), data.len(), 0); } int Socket::recv_data(Buffer &data) const { return recv(s, data.get(), data.len(), 0); } Buffer::Buffer(int len): size(len), data(new char[len]) {} char *Buffer::get() { return data.get(); } const char *Buffer::get() const { return data.get(); } int Buffer::len() const { return size; }