Files
winsock2_wrapper/socket.cpp
T
2026-04-03 20:51:58 +08:00

131 lines
2.7 KiB
C++

#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;
}