#include "IpTcpClient.h" #include #include "DataModel.h" constexpr unsigned int bufferSize = 256; IpTcpClient::IpTcpClient(const std::string targetIP, const unsigned int targetPort) : ip(targetIP), port(targetPort), lastRequest(TCP_REQUESTS::NA) { } IpTcpClient::IpTcpClient(std::string targetIP, unsigned int targetPort, TCP_REQUESTS requestCode) : IpTcpClient(targetIP, targetPort) { requestCode = requestCode; } void IpTcpClient::connect() { asio::error_code error; tcp::resolver resolver(context); endpoints = resolver.resolve(ip, std::to_string(port)); socket = std::make_unique(context); asio::connect(*socket, endpoints, error); if (error) { throw asio::system_error(error); } } void IpTcpClient::sendRequest(const TCP_REQUESTS& code) { this->lastRequest = code; inputStream.clear(); asio::error_code error; std::string codeString = "cmd:" + std::to_string(toUnderlyingType(code)) + '\n'; //Send the request code to server, which encodes the clients connection purpose size_t retVal = socket->write_some(asio::buffer(codeString), error); if (retVal == 0) { if (error == asio::error::eof) { //No error occured, sending finished std::cout << "Finnished sending request code" << std::endl; return; } throw asio::system_error(error); } } void IpTcpClient::processServerResponse() { if (TCP_REQUESTS::DOWNLOAD_DATA == lastRequest) { DataModel dataModel; inputStream >> dataModel; auto& savedData = dataModel.getSavedPublishedData(); std::cout << "Summary: " << std::endl; for (auto& id : savedData) { std::cout << "\tID " << id.first << ": " << id.second.size() << " datapoints" << std::endl; } } else if (TCP_REQUESTS::GET_STATUS == lastRequest) { std::cout << inputStream.str(); } } size_t IpTcpClient::waitRead() { size_t total_bytes_readed = 0, lastLen = 0; asio::error_code error; //std::array buf; //Loop for the input pipe, init with 3 ('Invalid') std::array codeBuffer; codeBuffer[0] = 3; while(1){ /*Get the serevrs intent CODE: 0: Invoke connection 1: Continuing 2: Finished 3: Invalid */ std::array buf; socket->read_some(asio::buffer(buf)); if (codeBuffer[0] != 1) //Steram does not continue break; //When stream continues while (codeBuffer[0] == 1) { size_t len = socket->read_some(asio::buffer(buf), error); total_bytes_readed += len; //Buffer as long as data readed if (len != 0) { std::cout << "Readed " << len << " bytes to buffer" << std::endl; if (len != bufferSize) lastLen = len; } // Connection closed cleanly by peer. if (error == asio::error::eof) { std::cout << "Transmition ended normally" << std::endl; break; } // Some other error. else if (error) { //Reply to server: 1 means failure std::arrayans { 1 }; socket->write_some(asio::buffer(ans)); throw asio::system_error(error); } std::string data = std::move(std::string(buf.begin(), lastLen == 0 ? buf.end() : buf.begin() + lastLen)); inputStream << data; } processServerResponse(); //Reply to server: 0 means okay codeBuffer[0] = 0; socket->write_some(asio::buffer(codeBuffer)); } return total_bytes_readed; }