/* Crafter®.Network Copyright (C) 2025 Catcrafts® Catcrafts.net This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ module; #include #include #include #include #include #include #include #include #include #include #include #include module Crafter.Network:ClientTCP_impl; import :ClientTCP; import Crafter.Thread; import std; using namespace Crafter; ClientTCP::ClientTCP(int socketid) : socketid(socketid) { } ClientTCP::ClientTCP(const char* hostName, std::uint16_t port) { hostent *host; sockaddr_in serv_addr; host=gethostbyname(hostName); if((socketid = socket(AF_INET, SOCK_STREAM, 0)) == -1){ std::cerr << "Could not open socket" << std::endl; } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(port); serv_addr.sin_addr = *((struct in_addr *)host->h_addr); bzero(&(serv_addr.sin_zero),8); if(connect(socketid,(sockaddr*)&serv_addr, sizeof(sockaddr)) == -1){ std::cerr << "Could not connect to server" << std::endl; } } ClientTCP::ClientTCP(std::string hostName, std::uint16_t port): ClientTCP(hostName.c_str(), port) { } ClientTCP::~ClientTCP() { close(socketid); } void ClientTCP::Send(const void* buffer, std::uint32_t size) const { send(socketid, reinterpret_cast(buffer), size, 0); } std::vector ClientTCP::RecieveSync(std::uint32_t bufferSize) const { std::vector totalBuffer(bufferSize); int read = recv(socketid, totalBuffer.data(), bufferSize, 0); if(read < bufferSize){ totalBuffer.resize(read); } return totalBuffer; } int ClientTCP::RecieveSync(std::uint32_t bufferSize, void* buffer) const { return recv(socketid, reinterpret_cast(buffer), bufferSize, 0); } std::vector ClientTCP::RecieveSync() const { int count; ioctl(socketid, FIONREAD, &count); std::vector buffer(count); recv(socketid, buffer.data(), count, 0); return buffer; } std::vector ClientTCP::RecieveUntilCloseSync() const { int count; ioctl(socketid, FIONREAD, &count); std::vector buffer(count); recv(socketid, buffer.data(), count, 0); while(true) { ioctl(socketid, FIONREAD, &count); unsigned int oldSize = buffer.size(); buffer.resize(buffer.size()+count); if(recv(socketid, buffer.data()+oldSize, count, 0) == -1) { break; } } return buffer; } std::vector ClientTCP::RecieveUntilFullSync(std::uint32_t bufferSize) const { std::vector buffer(bufferSize); int read = 0; while(read < bufferSize) { int newRead = recv(socketid, buffer.data()+read, bufferSize-read, 0); if(newRead == -1) { break; } else{ read+=newRead; } } buffer.resize(read); return buffer; } void ClientTCP::RecieveAsync(std::uint32_t bufferSize, std::function)> recieveCallback) const { ThreadPool::Enqueue([recieveCallback, this, bufferSize](){ recieveCallback(this->RecieveSync(bufferSize)); }); } void ClientTCP::RecieveAsync(std::uint32_t bufferSize, std::function recieveCallback, char* buffer) const { ThreadPool::Enqueue([recieveCallback, this, bufferSize, buffer](){ recieveCallback(this->RecieveSync(bufferSize, buffer)); }); } void ClientTCP::RecieveUntilFullAsync(std::uint32_t bufferSize, std::function)> recieveCallback) const { ThreadPool::Enqueue([recieveCallback, this, bufferSize](){ recieveCallback(this->RecieveUntilFullSync(bufferSize)); }); } void ClientTCP::RecieveAsync(std::function)> recieveCallback) const { ThreadPool::Enqueue([this, recieveCallback](){ recieveCallback(this->RecieveSync()); }); } void ClientTCP::RecieveUntilCloseAsync(std::function)> recieveCallback) const { ThreadPool::Enqueue([this, recieveCallback](){ recieveCallback(this->RecieveUntilCloseSync()); }); }