2021-12-07 22:47:57 +01:00
|
|
|
#include <hex/helpers/socket.hpp>
|
|
|
|
|
|
|
|
#include <hex/helpers/utils.hpp>
|
|
|
|
#include <hex/helpers/logger.hpp>
|
|
|
|
|
|
|
|
namespace hex {
|
|
|
|
|
|
|
|
Socket::Socket(const std::string &address, u16 port) {
|
2022-01-24 20:53:17 +01:00
|
|
|
#if defined(OS_WINDOWS)
|
|
|
|
FIRST_TIME {
|
|
|
|
WSAData wsa;
|
|
|
|
WSAStartup(MAKEWORD(2, 2), &wsa);
|
|
|
|
};
|
2021-12-07 22:47:57 +01:00
|
|
|
|
2022-01-24 20:53:17 +01:00
|
|
|
FINAL_CLEANUP {
|
|
|
|
WSACleanup();
|
|
|
|
};
|
|
|
|
#endif
|
2021-12-07 22:47:57 +01:00
|
|
|
|
|
|
|
this->connect(address, port);
|
|
|
|
}
|
|
|
|
|
2022-03-04 20:52:39 +01:00
|
|
|
Socket::Socket(Socket &&other) noexcept {
|
2022-02-01 22:09:44 +01:00
|
|
|
this->m_socket = other.m_socket;
|
2021-12-07 22:47:57 +01:00
|
|
|
this->m_connected = other.m_connected;
|
|
|
|
|
2021-12-07 23:09:30 +01:00
|
|
|
other.m_socket = SOCKET_NONE;
|
2021-12-07 22:47:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Socket::~Socket() {
|
|
|
|
this->disconnect();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Socket::writeBytes(const std::vector<u8> &bytes) const {
|
|
|
|
if (!this->isConnected()) return;
|
|
|
|
|
2022-01-24 20:53:17 +01:00
|
|
|
::send(this->m_socket, reinterpret_cast<const char *>(bytes.data()), bytes.size(), 0);
|
2021-12-07 22:47:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Socket::writeString(const std::string &string) const {
|
|
|
|
if (!this->isConnected()) return;
|
|
|
|
|
|
|
|
::send(this->m_socket, string.c_str(), string.length(), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<u8> Socket::readBytes(size_t size) const {
|
|
|
|
std::vector<u8> data;
|
|
|
|
data.resize(size);
|
|
|
|
|
|
|
|
auto receivedSize = ::recv(this->m_socket, reinterpret_cast<char *>(data.data()), size, 0);
|
|
|
|
|
|
|
|
if (receivedSize < 0)
|
2022-01-24 20:53:17 +01:00
|
|
|
return {};
|
2021-12-07 22:47:57 +01:00
|
|
|
|
|
|
|
data.resize(receivedSize);
|
|
|
|
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string Socket::readString(size_t size) const {
|
|
|
|
auto bytes = readBytes(size);
|
|
|
|
|
|
|
|
std::string result;
|
|
|
|
std::copy(bytes.begin(), bytes.end(), std::back_inserter(result));
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Socket::isConnected() const {
|
|
|
|
return this->m_connected;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Socket::connect(const std::string &address, u16 port) {
|
|
|
|
this->m_socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
2021-12-07 23:09:30 +01:00
|
|
|
if (this->m_socket == SOCKET_NONE)
|
2021-12-07 22:47:57 +01:00
|
|
|
return;
|
|
|
|
|
2022-03-27 00:01:28 +01:00
|
|
|
sockaddr_in client = { };
|
2021-12-07 22:47:57 +01:00
|
|
|
|
|
|
|
client.sin_family = AF_INET;
|
2022-02-01 22:09:44 +01:00
|
|
|
client.sin_port = htons(port);
|
2021-12-07 22:47:57 +01:00
|
|
|
|
2022-01-24 20:53:17 +01:00
|
|
|
#if defined(OS_WINDOWS)
|
|
|
|
client.sin_addr.S_un.S_addr = ::inet_addr(address.c_str());
|
|
|
|
#else
|
|
|
|
client.sin_addr.s_addr = ::inet_addr(address.c_str());
|
|
|
|
#endif
|
2021-12-07 23:09:30 +01:00
|
|
|
|
2022-01-24 20:53:17 +01:00
|
|
|
this->m_connected = ::connect(this->m_socket, reinterpret_cast<sockaddr *>(&client), sizeof(client)) == 0;
|
2021-12-07 22:47:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Socket::disconnect() {
|
2021-12-07 23:09:30 +01:00
|
|
|
if (this->m_socket != SOCKET_NONE) {
|
2022-01-24 20:53:17 +01:00
|
|
|
#if defined(OS_WINDOWS)
|
|
|
|
closesocket(this->m_socket);
|
|
|
|
#else
|
|
|
|
close(this->m_socket);
|
|
|
|
#endif
|
2021-12-07 23:09:30 +01:00
|
|
|
}
|
2021-12-07 22:47:57 +01:00
|
|
|
|
|
|
|
this->m_connected = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|