#include "socket/udp_socket.h" namespace Socket { UDPSocket::UDPSocket(int domain, int type, int protocol) { init(domain, type, protocol); } UDPSocket::~UDPSocket() { destruct(); } int UDPSocket::init(int domain, int type, int protocol) { this->domain = domain; sock = ::socket(domain, type, protocol); if (sock == INVALID_SOCKET) spdlog::critical("socket()"); valid_ = true; return 0; } void UDPSocket::destruct() { if (!valid_) return; #ifdef _WIN32 ::closesocket(sock); #elif __linux__ ::close(sock); #endif valid_ = false; } UDPSocket::operator SOCKET() { if (valid_) { valid_ = false; return sock; } spdlog::critical("No valid socket created."); return INVALID_SOCKET; } void UDPSocket::set(const SOCKET __sock, int __domain) { if (__sock == INVALID_SOCKET) { spdlog::critical("socket()"); std::exit(EXIT_FAILURE); } destruct(); sock = __sock; valid_ = true; }; int UDPSocket::setsockopt(int level, int optname, const char* optval, int optlen) { return ::setsockopt(sock, level, optname, optval, optlen); } int UDPSocket::bind(Address __addr) { bindAddr = __addr; int retVal = ::bind(sock, &__addr.addr, __addr.length); if (retVal == INVALID_SOCKET) { spdlog::critical("bind()"); std::exit(EXIT_FAILURE); } return retVal; } int UDPSocket::recvfrom(void* __restrict __buf, size_t __n, int __flags, struct Address& __addr) { std::lock_guard lock(readMutex); int retVal = ::recvfrom(sock, (char*)__buf, __n, __flags, &__addr.addr, &__addr.length); if (retVal == SOCKET_ERROR) spdlog::error("recvfrom()"); return retVal; } int UDPSocket::sendto(const void* __buf, size_t __n, int __flags, struct Address __addr) { std::lock_guard lock(writeMutex); int retVal = ::sendto(sock, (char*)__buf, __n, __flags, &__addr.addr, __addr.length); if (retVal == SOCKET_ERROR) spdlog::error("sendto()"); return retVal; } UDPSocket::UDPSocket(const UDPSocket& other_) { memcpy(this, &other_, sizeof(UDPSocket)); valid_ = false; } UDPSocket::UDPSocket(UDPSocket&& other_) noexcept { other_.valid_ = false; memcpy(this, &other_, sizeof(UDPSocket)); valid_ = true; } UDPSocket& UDPSocket::operator=(const UDPSocket& other_) { memcpy(this, &other_, sizeof(UDPSocket)); valid_ = false; return *this; } UDPSocket& UDPSocket::operator=(UDPSocket&& other_) noexcept { other_.valid_ = false; memcpy(this, &other_, sizeof(UDPSocket)); valid_ = true; return *this; } } // namespace Socket