131 lines
2.7 KiB
C++
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;
|
|
}
|