Format all the code

This commit is contained in:
momo5502
2025-01-06 17:13:33 +01:00
parent 64c2a79f0f
commit bff8420ffd
100 changed files with 16439 additions and 14509 deletions

View File

@@ -8,376 +8,365 @@ using namespace std::literals;
namespace network
{
void initialize_wsa()
{
void initialize_wsa()
{
#ifdef _WIN32
static struct wsa_initializer
{
public:
wsa_initializer()
{
WSADATA wsa_data;
if (WSAStartup(MAKEWORD(2, 2), &wsa_data))
{
throw std::runtime_error("Unable to initialize WSA");
}
}
static struct wsa_initializer
{
wsa_initializer()
{
WSADATA wsa_data;
if (WSAStartup(MAKEWORD(2, 2), &wsa_data))
{
throw std::runtime_error("Unable to initialize WSA");
}
}
~wsa_initializer()
{
WSACleanup();
}
} _;
~wsa_initializer()
{
WSACleanup();
}
} _;
#endif
}
}
address::address()
{
initialize_wsa();
ZeroMemory(&this->storage_, this->get_max_size());
address::address()
{
initialize_wsa();
ZeroMemory(&this->storage_, this->get_max_size());
this->address_.sa_family = AF_UNSPEC;
}
this->address_.sa_family = AF_UNSPEC;
}
address::address(const std::string& addr, const std::optional<int>& family)
: address()
{
this->parse(addr, family);
}
address::address(const std::string& addr, const std::optional<int>& family)
: address()
{
this->parse(addr, family);
}
address::address(const sockaddr_in6& addr)
: address()
{
this->address6_ = addr;
}
address::address(const sockaddr_in6& addr)
: address()
{
this->address6_ = addr;
}
address::address(const sockaddr_in& addr)
: address()
{
this->address4_ = addr;
}
address::address(const sockaddr_in& addr)
: address()
{
this->address4_ = addr;
}
address::address(const sockaddr* addr, const socklen_t length)
: address()
{
this->set_address(addr, length);
}
address::address(const sockaddr* addr, const socklen_t length)
: address()
{
this->set_address(addr, length);
}
void address::set_ipv4(const uint32_t ip)
{
in_addr addr{};
addr.s_addr = ip;
this->set_ipv4(addr);
}
void address::set_ipv4(const uint32_t ip)
{
in_addr addr{};
addr.s_addr = ip;
this->set_ipv4(addr);
}
bool address::operator==(const address& obj) const
{
if (this->address_.sa_family != obj.address_.sa_family)
{
return false;
}
bool address::operator==(const address& obj) const
{
if (this->address_.sa_family != obj.address_.sa_family)
{
return false;
}
if (this->get_port() != obj.get_port())
{
return false;
}
if (this->get_port() != obj.get_port())
{
return false;
}
if (this->address_.sa_family == AF_INET)
{
return this->address4_.sin_addr.s_addr == obj.address4_.sin_addr.s_addr;
}
else if (this->address_.sa_family == AF_INET6)
{
return !memcmp(this->address6_.sin6_addr.s6_addr, obj.address6_.sin6_addr.s6_addr,
sizeof(obj.address6_.sin6_addr.s6_addr));
}
if (this->address_.sa_family == AF_INET)
{
return this->address4_.sin_addr.s_addr == obj.address4_.sin_addr.s_addr;
}
else if (this->address_.sa_family == AF_INET6)
{
return !memcmp(this->address6_.sin6_addr.s6_addr, obj.address6_.sin6_addr.s6_addr,
sizeof(obj.address6_.sin6_addr.s6_addr));
}
return false;
}
return false;
}
void address::set_ipv4(const in_addr& addr)
{
ZeroMemory(&this->address4_, sizeof(this->address4_));
this->address4_.sin_family = AF_INET;
this->address4_.sin_addr = addr;
}
void address::set_ipv4(const in_addr& addr)
{
ZeroMemory(&this->address4_, sizeof(this->address4_));
this->address4_.sin_family = AF_INET;
this->address4_.sin_addr = addr;
}
void address::set_ipv6(const in6_addr& addr)
{
ZeroMemory(&this->address6_, sizeof(this->address6_));
this->address6_.sin6_family = AF_INET6;
this->address6_.sin6_addr = addr;
}
void address::set_ipv6(const in6_addr& addr)
{
ZeroMemory(&this->address6_, sizeof(this->address6_));
this->address6_.sin6_family = AF_INET6;
this->address6_.sin6_addr = addr;
}
void address::set_address(const sockaddr* addr, const socklen_t length)
{
if (static_cast<size_t>(length) >= sizeof(sockaddr_in) && addr->sa_family == AF_INET)
{
this->address4_ = *reinterpret_cast<const sockaddr_in*>(addr);
}
else if (static_cast<size_t>(length) == sizeof(sockaddr_in6) && addr->sa_family == AF_INET6)
{
this->address6_ = *reinterpret_cast<const sockaddr_in6*>(addr);
}
else
{
throw std::runtime_error("Invalid network address");
}
}
void address::set_address(const sockaddr* addr, const socklen_t length)
{
if (static_cast<size_t>(length) >= sizeof(sockaddr_in) && addr->sa_family == AF_INET)
{
this->address4_ = *reinterpret_cast<const sockaddr_in*>(addr);
}
else if (static_cast<size_t>(length) == sizeof(sockaddr_in6) && addr->sa_family == AF_INET6)
{
this->address6_ = *reinterpret_cast<const sockaddr_in6*>(addr);
}
else
{
throw std::runtime_error("Invalid network address");
}
}
void address::set_port(const unsigned short port)
{
switch (this->address_.sa_family)
{
case AF_INET:
this->address4_.sin_port = htons(port);
break;
case AF_INET6:
this->address6_.sin6_port = htons(port);
break;
default:
throw std::runtime_error("Invalid address family");
}
}
void address::set_port(const unsigned short port)
{
switch (this->address_.sa_family)
{
case AF_INET:
this->address4_.sin_port = htons(port);
break;
case AF_INET6:
this->address6_.sin6_port = htons(port);
break;
default:
throw std::runtime_error("Invalid address family");
}
}
unsigned short address::get_port() const
{
switch (this->address_.sa_family)
{
case AF_INET:
return ntohs(this->address4_.sin_port);
case AF_INET6:
return ntohs(this->address6_.sin6_port);
default:
return 0;
}
}
unsigned short address::get_port() const
{
switch (this->address_.sa_family)
{
case AF_INET:
return ntohs(this->address4_.sin_port);
case AF_INET6:
return ntohs(this->address6_.sin6_port);
default:
return 0;
}
}
std::string address::to_string() const
{
char buffer[1000] = {0};
std::string addr;
std::string address::to_string() const
{
char buffer[1000] = {0};
std::string addr;
switch (this->address_.sa_family)
{
case AF_INET:
inet_ntop(this->address_.sa_family, &this->address4_.sin_addr, buffer, sizeof(buffer));
addr = std::string(buffer);
break;
case AF_INET6:
inet_ntop(this->address_.sa_family, &this->address6_.sin6_addr, buffer, sizeof(buffer));
addr = "[" + std::string(buffer) + "]";
break;
default:
buffer[0] = '?';
buffer[1] = 0;
addr = std::string(buffer);
break;
}
switch (this->address_.sa_family)
{
case AF_INET:
inet_ntop(this->address_.sa_family, &this->address4_.sin_addr, buffer, sizeof(buffer));
addr = std::string(buffer);
break;
case AF_INET6:
inet_ntop(this->address_.sa_family, &this->address6_.sin6_addr, buffer, sizeof(buffer));
addr = "[" + std::string(buffer) + "]";
break;
default:
buffer[0] = '?';
buffer[1] = 0;
addr = std::string(buffer);
break;
}
return addr + ":"s + std::to_string(this->get_port());
}
return addr + ":"s + std::to_string(this->get_port());
}
bool address::is_local() const
{
if (this->address_.sa_family != AF_INET)
{
return false;
}
bool address::is_local() const
{
if (this->address_.sa_family != AF_INET)
{
return false;
}
// According to: https://en.wikipedia.org/wiki/Private_network
// According to: https://en.wikipedia.org/wiki/Private_network
uint8_t bytes[4];
*reinterpret_cast<uint32_t*>(&bytes) = this->address4_.sin_addr.s_addr;
uint8_t bytes[4];
*reinterpret_cast<uint32_t*>(&bytes) = this->address4_.sin_addr.s_addr;
// 10.X.X.X
if (bytes[0] == 10)
{
return true;
}
// 10.X.X.X
if (bytes[0] == 10)
{
return true;
}
// 192.168.X.X
if (bytes[0] == 192
&& bytes[1] == 168)
{
return true;
}
// 192.168.X.X
if (bytes[0] == 192 && bytes[1] == 168)
{
return true;
}
// 172.16.X.X - 172.31.X.X
if (bytes[0] == 172
&& bytes[1] >= 16
&& bytes[1] < 32)
{
return true;
}
// 172.16.X.X - 172.31.X.X
if (bytes[0] == 172 && bytes[1] >= 16 && bytes[1] < 32)
{
return true;
}
// 127.0.0.1
if (this->address4_.sin_addr.s_addr == 0x0100007F)
{
return true;
}
// 127.0.0.1
if (this->address4_.sin_addr.s_addr == 0x0100007F)
{
return true;
}
return false;
}
return false;
}
sockaddr& address::get_addr()
{
return this->address_;
}
sockaddr& address::get_addr()
{
return this->address_;
}
const sockaddr& address::get_addr() const
{
return this->address_;
}
const sockaddr& address::get_addr() const
{
return this->address_;
}
sockaddr_in& address::get_in_addr()
{
return this->address4_;
}
sockaddr_in& address::get_in_addr()
{
return this->address4_;
}
sockaddr_in6& address::get_in6_addr()
{
return this->address6_;
}
sockaddr_in6& address::get_in6_addr()
{
return this->address6_;
}
const sockaddr_in& address::get_in_addr() const
{
return this->address4_;
}
const sockaddr_in& address::get_in_addr() const
{
return this->address4_;
}
const sockaddr_in6& address::get_in6_addr() const
{
return this->address6_;
}
const sockaddr_in6& address::get_in6_addr() const
{
return this->address6_;
}
socklen_t address::get_size() const
{
switch (this->address_.sa_family)
{
case AF_INET:
return static_cast<socklen_t>(sizeof(this->address4_));
case AF_INET6:
return static_cast<socklen_t>(sizeof(this->address6_));
default:
return static_cast<socklen_t>(sizeof(this->address_));
}
}
socklen_t address::get_size() const
{
switch (this->address_.sa_family)
{
case AF_INET:
return static_cast<socklen_t>(sizeof(this->address4_));
case AF_INET6:
return static_cast<socklen_t>(sizeof(this->address6_));
default:
return static_cast<socklen_t>(sizeof(this->address_));
}
}
socklen_t address::get_max_size() const
{
constexpr auto s = sizeof(this->address_);
constexpr auto s4 = sizeof(this->address4_);
constexpr auto s6 = sizeof(this->address6_);
constexpr auto sstore = sizeof(this->storage_);
constexpr auto max_size = std::max(sstore, std::max(s, std::max(s4, s6)));
static_assert(max_size == sstore);
socklen_t address::get_max_size() const
{
constexpr auto s = sizeof(this->address_);
constexpr auto s4 = sizeof(this->address4_);
constexpr auto s6 = sizeof(this->address6_);
constexpr auto sstore = sizeof(this->storage_);
constexpr auto max_size = std::max(sstore, std::max(s, std::max(s4, s6)));
static_assert(max_size == sstore);
return static_cast<socklen_t>(max_size);
}
return static_cast<socklen_t>(max_size);
}
bool address::is_ipv4() const
{
return this->address_.sa_family == AF_INET;
}
bool address::is_ipv4() const
{
return this->address_.sa_family == AF_INET;
}
bool address::is_ipv6() const
{
return this->address_.sa_family == AF_INET6;
}
bool address::is_ipv6() const
{
return this->address_.sa_family == AF_INET6;
}
bool address::is_supported() const
{
return is_ipv4() || is_ipv6();
}
bool address::is_supported() const
{
return is_ipv4() || is_ipv6();
}
void address::parse(std::string addr, const std::optional<int>& family)
{
std::optional<uint16_t> port_value{};
void address::parse(std::string addr, const std::optional<int>& family)
{
std::optional<uint16_t> port_value{};
const auto pos = addr.find_last_of(':');
if (pos != std::string::npos)
{
auto port = addr.substr(pos + 1);
port_value = uint16_t(atoi(port.data()));
addr = addr.substr(0, pos);
}
const auto pos = addr.find_last_of(':');
if (pos != std::string::npos)
{
auto port = addr.substr(pos + 1);
port_value = uint16_t(atoi(port.data()));
addr = addr.substr(0, pos);
}
this->resolve(addr, family);
this->resolve(addr, family);
if (port_value)
{
this->set_port(*port_value);
}
}
if (port_value)
{
this->set_port(*port_value);
}
}
void address::resolve(const std::string& hostname, const std::optional<int>& family)
{
const auto port = this->get_port();
auto port_reset_action = utils::finally([this, port]()
{
this->set_port(port);
});
void address::resolve(const std::string& hostname, const std::optional<int>& family)
{
const auto port = this->get_port();
auto port_reset_action = utils::finally([this, port]() { this->set_port(port); });
const auto result = resolve_multiple(hostname);
for (const auto& addr : result)
{
if (addr.is_supported() && (!family || addr.get_addr().sa_family == *family))
{
this->set_address(&addr.get_addr(), addr.get_size());
return;
}
}
const auto result = resolve_multiple(hostname);
for (const auto& addr : result)
{
if (addr.is_supported() && (!family || addr.get_addr().sa_family == *family))
{
this->set_address(&addr.get_addr(), addr.get_size());
return;
}
}
port_reset_action.cancel();
throw std::runtime_error{"Unable to resolve hostname: " + hostname};
}
port_reset_action.cancel();
throw std::runtime_error{"Unable to resolve hostname: " + hostname};
}
std::vector<address> address::resolve_multiple(const std::string& hostname)
{
std::vector<address> results{};
std::vector<address> address::resolve_multiple(const std::string& hostname)
{
std::vector<address> results{};
addrinfo* result = nullptr;
if (!getaddrinfo(hostname.data(), nullptr, nullptr, &result))
{
const auto _2 = utils::finally([&result]
{
freeaddrinfo(result);
});
addrinfo* result = nullptr;
if (!getaddrinfo(hostname.data(), nullptr, nullptr, &result))
{
const auto _2 = utils::finally([&result] { freeaddrinfo(result); });
for (auto* i = result; i; i = i->ai_next)
{
if (i->ai_family == AF_INET || i->ai_family == AF_INET6)
{
address a{};
a.set_address(i->ai_addr, static_cast<socklen_t>(i->ai_addrlen));
results.emplace_back(std::move(a));
}
}
}
for (auto* i = result; i; i = i->ai_next)
{
if (i->ai_family == AF_INET || i->ai_family == AF_INET6)
{
address a{};
a.set_address(i->ai_addr, static_cast<socklen_t>(i->ai_addrlen));
results.emplace_back(std::move(a));
}
}
}
return results;
}
return results;
}
}
std::size_t std::hash<network::address>::operator()(const network::address& a) const noexcept
{
const uint32_t family = a.get_addr().sa_family;
const uint32_t port = a.get_port();
const uint32_t family = a.get_addr().sa_family;
const uint32_t port = a.get_port();
std::size_t hash = std::hash<uint32_t>{}(family);
hash ^= std::hash<uint32_t>{}(port);
switch (a.get_addr().sa_family)
{
case AF_INET:
hash ^= std::hash<decltype(a.get_in_addr().sin_addr.s_addr)>{}(a.get_in_addr().sin_addr.s_addr);
break;
case AF_INET6:
hash ^= std::hash<std::string_view>{}(std::string_view{
reinterpret_cast<const char*>(a.get_in6_addr().sin6_addr.s6_addr),
sizeof(a.get_in6_addr().sin6_addr.s6_addr)
});
break;
}
std::size_t hash = std::hash<uint32_t>{}(family);
hash ^= std::hash<uint32_t>{}(port);
switch (a.get_addr().sa_family)
{
case AF_INET:
hash ^= std::hash<decltype(a.get_in_addr().sin_addr.s_addr)>{}(a.get_in_addr().sin_addr.s_addr);
break;
case AF_INET6:
hash ^= std::hash<std::string_view>{}(
std::string_view{reinterpret_cast<const char*>(a.get_in6_addr().sin6_addr.s6_addr),
sizeof(a.get_in6_addr().sin6_addr.s6_addr)});
break;
}
return hash;
return hash;
}

View File

@@ -36,71 +36,71 @@ using socklen_t = int;
namespace network
{
void initialize_wsa();
void initialize_wsa();
class address
{
public:
address();
address(const std::string& addr, const std::optional<int>& family = {});
address(const sockaddr_in& addr);
address(const sockaddr_in6& addr);
address(const sockaddr* addr, socklen_t length);
class address
{
public:
address();
address(const std::string& addr, const std::optional<int>& family = {});
address(const sockaddr_in& addr);
address(const sockaddr_in6& addr);
address(const sockaddr* addr, socklen_t length);
void set_ipv4(uint32_t ip);
void set_ipv4(const in_addr& addr);
void set_ipv6(const in6_addr& addr);
void set_address(const sockaddr* addr, socklen_t length);
void set_ipv4(uint32_t ip);
void set_ipv4(const in_addr& addr);
void set_ipv6(const in6_addr& addr);
void set_address(const sockaddr* addr, socklen_t length);
void set_port(unsigned short port);
[[nodiscard]] unsigned short get_port() const;
void set_port(unsigned short port);
[[nodiscard]] unsigned short get_port() const;
sockaddr& get_addr();
sockaddr_in& get_in_addr();
sockaddr_in6& get_in6_addr();
sockaddr& get_addr();
sockaddr_in& get_in_addr();
sockaddr_in6& get_in6_addr();
const sockaddr& get_addr() const;
const sockaddr_in& get_in_addr() const;
const sockaddr_in6& get_in6_addr() const;
const sockaddr& get_addr() const;
const sockaddr_in& get_in_addr() const;
const sockaddr_in6& get_in6_addr() const;
socklen_t get_size() const;
socklen_t get_max_size() const;
socklen_t get_size() const;
socklen_t get_max_size() const;
bool is_ipv4() const;
bool is_ipv6() const;
bool is_supported() const;
bool is_ipv4() const;
bool is_ipv6() const;
bool is_supported() const;
[[nodiscard]] bool is_local() const;
[[nodiscard]] std::string to_string() const;
[[nodiscard]] bool is_local() const;
[[nodiscard]] std::string to_string() const;
bool operator==(const address& obj) const;
bool operator==(const address& obj) const;
bool operator!=(const address& obj) const
{
return !(*this == obj);
}
bool operator!=(const address& obj) const
{
return !(*this == obj);
}
static std::vector<address> resolve_multiple(const std::string& hostname);
static std::vector<address> resolve_multiple(const std::string& hostname);
private:
union
{
sockaddr address_;
sockaddr_in address4_;
sockaddr_in6 address6_;
sockaddr_storage storage_;
};
private:
union
{
sockaddr address_;
sockaddr_in address4_;
sockaddr_in6 address6_;
sockaddr_storage storage_;
};
void parse(std::string addr, const std::optional<int>& family = {});
void resolve(const std::string& hostname, const std::optional<int>& family = {});
};
void parse(std::string addr, const std::optional<int>& family = {});
void resolve(const std::string& hostname, const std::optional<int>& family = {});
};
}
namespace std
{
template <>
struct hash<network::address>
{
std::size_t operator()(const network::address& a) const noexcept;
};
template <>
struct hash<network::address>
{
std::size_t operator()(const network::address& a) const noexcept;
};
}

View File

@@ -6,226 +6,225 @@ using namespace std::literals;
namespace network
{
socket::socket(const int af)
: address_family_(af)
{
initialize_wsa();
this->socket_ = ::socket(af, SOCK_DGRAM, IPPROTO_UDP);
socket::socket(const int af)
: address_family_(af)
{
initialize_wsa();
this->socket_ = ::socket(af, SOCK_DGRAM, IPPROTO_UDP);
if (af == AF_INET6)
{
int i = 1;
setsockopt(this->socket_, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<char*>(&i),
static_cast<int>(sizeof(i)));
}
}
if (af == AF_INET6)
{
int i = 1;
setsockopt(this->socket_, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<char*>(&i),
static_cast<int>(sizeof(i)));
}
}
socket::~socket()
{
this->release();
}
socket::~socket()
{
this->release();
}
socket::socket(socket&& obj) noexcept
{
this->operator=(std::move(obj));
}
socket::socket(socket&& obj) noexcept
{
this->operator=(std::move(obj));
}
socket& socket::operator=(socket&& obj) noexcept
{
if (this != &obj)
{
this->release();
this->socket_ = obj.socket_;
this->port_ = obj.port_;
this->address_family_ = obj.address_family_;
socket& socket::operator=(socket&& obj) noexcept
{
if (this != &obj)
{
this->release();
this->socket_ = obj.socket_;
this->port_ = obj.port_;
this->address_family_ = obj.address_family_;
obj.socket_ = INVALID_SOCKET;
obj.address_family_ = AF_UNSPEC;
}
obj.socket_ = INVALID_SOCKET;
obj.address_family_ = AF_UNSPEC;
}
return *this;
}
return *this;
}
void socket::release()
{
if (this->socket_ != INVALID_SOCKET)
{
closesocket(this->socket_);
this->socket_ = INVALID_SOCKET;
}
}
void socket::release()
{
if (this->socket_ != INVALID_SOCKET)
{
closesocket(this->socket_);
this->socket_ = INVALID_SOCKET;
}
}
bool socket::bind_port(const address& target)
{
const auto result = bind(this->socket_, &target.get_addr(), target.get_size()) == 0;
if (result)
{
this->port_ = target.get_port();
}
bool socket::bind_port(const address& target)
{
const auto result = bind(this->socket_, &target.get_addr(), target.get_size()) == 0;
if (result)
{
this->port_ = target.get_port();
}
return result;
}
return result;
}
bool socket::send(const address& target, const void* data, const size_t size) const
{
const auto res = sendto(this->socket_, static_cast<const char*>(data), static_cast<send_size>(size), 0,
&target.get_addr(),
target.get_size());
return static_cast<size_t>(res) == size;
}
bool socket::send(const address& target, const void* data, const size_t size) const
{
const auto res = sendto(this->socket_, static_cast<const char*>(data), static_cast<send_size>(size), 0,
&target.get_addr(), target.get_size());
return static_cast<size_t>(res) == size;
}
bool socket::send(const address& target, const std::string& data) const
{
return this->send(target, data.data(), data.size());
}
bool socket::send(const address& target, const std::string& data) const
{
return this->send(target, data.data(), data.size());
}
bool socket::receive(address& source, std::string& data) const
{
char buffer[0x2000];
auto len = source.get_max_size();
bool socket::receive(address& source, std::string& data) const
{
char buffer[0x2000];
auto len = source.get_max_size();
const auto result = recvfrom(this->socket_, buffer, static_cast<int>(sizeof(buffer)), 0, &source.get_addr(),
&len);
if (result == SOCKET_ERROR)
{
return false;
}
const auto result =
recvfrom(this->socket_, buffer, static_cast<int>(sizeof(buffer)), 0, &source.get_addr(), &len);
if (result == SOCKET_ERROR)
{
return false;
}
data.assign(buffer, buffer + result);
return true;
}
data.assign(buffer, buffer + result);
return true;
}
bool socket::set_blocking(const bool blocking)
{
return socket::set_blocking(this->socket_, blocking);
}
bool socket::set_blocking(const bool blocking)
{
return socket::set_blocking(this->socket_, blocking);
}
bool socket::set_blocking(SOCKET s, const bool blocking)
{
bool socket::set_blocking(SOCKET s, const bool blocking)
{
#ifdef _WIN32
unsigned long mode = blocking ? 0 : 1;
return ioctlsocket(s, FIONBIO, &mode) == 0;
unsigned long mode = blocking ? 0 : 1;
return ioctlsocket(s, FIONBIO, &mode) == 0;
#else
int flags = fcntl(s, F_GETFL, 0);
if (flags == -1) return false;
flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
return fcntl(s, F_SETFL, flags) == 0;
int flags = fcntl(s, F_GETFL, 0);
if (flags == -1)
return false;
flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
return fcntl(s, F_SETFL, flags) == 0;
#endif
}
}
bool socket::sleep(const std::chrono::milliseconds timeout) const
{
/*fd_set fdr;
FD_ZERO(&fdr);
FD_SET(this->socket_, &fdr);
bool socket::sleep(const std::chrono::milliseconds timeout) const
{
/*fd_set fdr;
FD_ZERO(&fdr);
FD_SET(this->socket_, &fdr);
const auto msec = timeout.count();
const auto msec = timeout.count();
timeval tv{};
tv.tv_sec = static_cast<long>(msec / 1000ll);
tv.tv_usec = static_cast<long>((msec % 1000) * 1000);
timeval tv{};
tv.tv_sec = static_cast<long>(msec / 1000ll);
tv.tv_usec = static_cast<long>((msec % 1000) * 1000);
const auto retval = select(static_cast<int>(this->socket_) + 1, &fdr, nullptr, nullptr, &tv);
if (retval == SOCKET_ERROR)
{
std::this_thread::sleep_for(1ms);
return socket_is_ready;
}
const auto retval = select(static_cast<int>(this->socket_) + 1, &fdr, nullptr, nullptr, &tv);
if (retval == SOCKET_ERROR)
{
std::this_thread::sleep_for(1ms);
return socket_is_ready;
}
if (retval > 0)
{
return socket_is_ready;
}
if (retval > 0)
{
return socket_is_ready;
}
return !socket_is_ready;*/
return !socket_is_ready;*/
std::vector<const socket*> sockets{};
sockets.push_back(this);
std::vector<const socket*> sockets{};
sockets.push_back(this);
return sleep_sockets(sockets, timeout);
}
return sleep_sockets(sockets, timeout);
}
bool socket::sleep_until(const std::chrono::high_resolution_clock::time_point time_point) const
{
const auto duration = time_point - std::chrono::high_resolution_clock::now();
return this->sleep(std::chrono::duration_cast<std::chrono::milliseconds>(duration));
}
bool socket::sleep_until(const std::chrono::high_resolution_clock::time_point time_point) const
{
const auto duration = time_point - std::chrono::high_resolution_clock::now();
return this->sleep(std::chrono::duration_cast<std::chrono::milliseconds>(duration));
}
SOCKET socket::get_socket() const
{
return this->socket_;
}
SOCKET socket::get_socket() const
{
return this->socket_;
}
uint16_t socket::get_port() const
{
return this->port_;
}
uint16_t socket::get_port() const
{
return this->port_;
}
int socket::get_address_family() const
{
return this->address_family_;
}
int socket::get_address_family() const
{
return this->address_family_;
}
bool socket::sleep_sockets(const std::span<const socket*>& sockets, const std::chrono::milliseconds timeout)
{
std::vector<pollfd> pfds{};
pfds.resize(sockets.size());
bool socket::sleep_sockets(const std::span<const socket*>& sockets, const std::chrono::milliseconds timeout)
{
std::vector<pollfd> pfds{};
pfds.resize(sockets.size());
for (size_t i = 0; i < sockets.size(); ++i)
{
auto& pfd = pfds.at(i);
const auto& socket = sockets[i];
for (size_t i = 0; i < sockets.size(); ++i)
{
auto& pfd = pfds.at(i);
const auto& socket = sockets[i];
pfd.fd = socket->get_socket();
pfd.events = POLLIN;
pfd.revents = 0;
}
pfd.fd = socket->get_socket();
pfd.events = POLLIN;
pfd.revents = 0;
}
const auto retval = poll(pfds.data(), static_cast<uint32_t>(pfds.size()),
static_cast<int>(timeout.count()));
const auto retval = poll(pfds.data(), static_cast<uint32_t>(pfds.size()), static_cast<int>(timeout.count()));
if (retval == SOCKET_ERROR)
{
std::this_thread::sleep_for(1ms);
return socket_is_ready;
}
if (retval == SOCKET_ERROR)
{
std::this_thread::sleep_for(1ms);
return socket_is_ready;
}
if (retval > 0)
{
return socket_is_ready;
}
if (retval > 0)
{
return socket_is_ready;
}
return !socket_is_ready;
}
return !socket_is_ready;
}
bool socket::is_socket_ready(const SOCKET s, const bool in_poll)
{
pollfd pfd{};
bool socket::is_socket_ready(const SOCKET s, const bool in_poll)
{
pollfd pfd{};
pfd.fd = s;
pfd.events = in_poll ? POLLIN : POLLOUT;
pfd.revents = 0;
pfd.fd = s;
pfd.events = in_poll ? POLLIN : POLLOUT;
pfd.revents = 0;
const auto retval = poll(&pfd, 1, 0);
const auto retval = poll(&pfd, 1, 0);
if (retval == SOCKET_ERROR)
{
std::this_thread::sleep_for(1ms);
return socket_is_ready;
}
if (retval == SOCKET_ERROR)
{
std::this_thread::sleep_for(1ms);
return socket_is_ready;
}
if (retval > 0)
{
return socket_is_ready;
}
if (retval > 0)
{
return socket_is_ready;
}
return !socket_is_ready;
}
return !socket_is_ready;
}
bool socket::sleep_sockets_until(const std::span<const socket*>& sockets,
const std::chrono::high_resolution_clock::time_point time_point)
{
const auto duration = time_point - std::chrono::high_resolution_clock::now();
return sleep_sockets(sockets, std::chrono::duration_cast<std::chrono::milliseconds>(duration));
}
bool socket::sleep_sockets_until(const std::span<const socket*>& sockets,
const std::chrono::high_resolution_clock::time_point time_point)
{
const auto duration = time_point - std::chrono::high_resolution_clock::now();
return sleep_sockets(sockets, std::chrono::duration_cast<std::chrono::milliseconds>(duration));
}
}

View File

@@ -8,63 +8,63 @@
#ifdef _WIN32
using send_size = int;
#define GET_SOCKET_ERROR() (WSAGetLastError())
#define poll WSAPoll
#define SOCK_WOULDBLOCK WSAEWOULDBLOCK
#define poll WSAPoll
#define SOCK_WOULDBLOCK WSAEWOULDBLOCK
#else
using SOCKET = int;
using send_size = size_t;
#define INVALID_SOCKET (SOCKET)(~0)
#define SOCKET_ERROR (-1)
#define INVALID_SOCKET (SOCKET)(~0)
#define SOCKET_ERROR (-1)
#define GET_SOCKET_ERROR() (errno)
#define closesocket close
#define SOCK_WOULDBLOCK EWOULDBLOCK
#define closesocket close
#define SOCK_WOULDBLOCK EWOULDBLOCK
#endif
namespace network
{
class socket
{
public:
socket() = default;
class socket
{
public:
socket() = default;
socket(int af);
~socket();
socket(int af);
~socket();
socket(const socket& obj) = delete;
socket& operator=(const socket& obj) = delete;
socket(const socket& obj) = delete;
socket& operator=(const socket& obj) = delete;
socket(socket&& obj) noexcept;
socket& operator=(socket&& obj) noexcept;
socket(socket&& obj) noexcept;
socket& operator=(socket&& obj) noexcept;
bool bind_port(const address& target);
bool bind_port(const address& target);
[[maybe_unused]] bool send(const address& target, const void* data, size_t size) const;
[[maybe_unused]] bool send(const address& target, const std::string& data) const;
bool receive(address& source, std::string& data) const;
[[maybe_unused]] bool send(const address& target, const void* data, size_t size) const;
[[maybe_unused]] bool send(const address& target, const std::string& data) const;
bool receive(address& source, std::string& data) const;
bool set_blocking(bool blocking);
static bool set_blocking(SOCKET s, bool blocking);
bool set_blocking(bool blocking);
static bool set_blocking(SOCKET s, bool blocking);
static constexpr bool socket_is_ready = true;
bool sleep(std::chrono::milliseconds timeout) const;
bool sleep_until(std::chrono::high_resolution_clock::time_point time_point) const;
static constexpr bool socket_is_ready = true;
bool sleep(std::chrono::milliseconds timeout) const;
bool sleep_until(std::chrono::high_resolution_clock::time_point time_point) const;
SOCKET get_socket() const;
uint16_t get_port() const;
SOCKET get_socket() const;
uint16_t get_port() const;
int get_address_family() const;
int get_address_family() const;
static bool sleep_sockets(const std::span<const socket*>& sockets, std::chrono::milliseconds timeout);
static bool sleep_sockets_until(const std::span<const socket*>& sockets,
std::chrono::high_resolution_clock::time_point time_point);
static bool sleep_sockets(const std::span<const socket*>& sockets, std::chrono::milliseconds timeout);
static bool sleep_sockets_until(const std::span<const socket*>& sockets,
std::chrono::high_resolution_clock::time_point time_point);
static bool is_socket_ready(SOCKET s, bool in_poll);
static bool is_socket_ready(SOCKET s, bool in_poll);
private:
int address_family_{AF_UNSPEC};
uint16_t port_ = 0;
SOCKET socket_ = INVALID_SOCKET;
private:
int address_family_{AF_UNSPEC};
uint16_t port_ = 0;
SOCKET socket_ = INVALID_SOCKET;
void release();
};
void release();
};
}