|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- //Simulation of an external IP-TCP client using ASIO lib
-
- #include <iostream>
- #include "asio.hpp"
- #include <iostream>
- #include <array>
- #include <sstream>
- #include <string>
- #include <fstream>
- #include "PublisherData.h"
- #include "DataModel.h"
- #include "IpTcpClient.h"
- #include "NetClient.h"
- #include <fstream>
- #include <filesystem>
- #include <thread>
- #include <memory>
- #include <atomic>
- #include <regex>
- #include "easylogging++.h"
- INITIALIZE_EASYLOGGINGPP
-
- constexpr unsigned int BUFFER_SIZE = 256;
- //Format of Date in the log files
- constexpr char logDateFormat[] = "%Y-%m-%d %H:%M:%S";
- constexpr unsigned short DATE_HEADER_SIZE = 19;
- const auto session_id = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
- using asio::ip::tcp;
-
-
- std::atomic_char keyboardInput = '0';
-
- void readInput() {
- while (1){
- keyboardInput = std::cin.get();
- std::cin.get();
- }
- }
-
- //Takes a message with log file body and extracts the last written log date
- //This values is taken for the next log file downloading, to minimize download data size
- //and prevent the aplication from downloading data twice
- long long parseDate(net::Message<net::MessageTypes>& msg) {
- if (msg.header.size < DATE_HEADER_SIZE)
- return 0;
-
- std::stringstream ss;
- //Find last occurence of '\n' with reverse iteration
- auto res = std::find_if(msg.body.rbegin(), msg.body.rend(),
- [](const uint8_t i) { return i == '\n'; });
- if (res == msg.body.rend()) {
- //No occurence of '\n', log file is empty
- return 0;
- }
- //Find last but one occurence of '\n' using reverse iteration
- res = std::find_if(res+1, msg.body.rend(),
- [](const uint8_t i) { return i == '\n'; });
- if (res == msg.body.rend()) {
- //No second occurence of '\n'
- //-> only one line of log, set iterator to first position
- res = msg.body.rend();
- }
- //Extreact the header and parse it to proper date format
- for (size_t i = 0; i < DATE_HEADER_SIZE; i++) {
- ss << *(--res);
- }
- std::tm tm = {};
- ss >> std::get_time(&tm, logDateFormat);
- long long tp = std::chrono::system_clock::from_time_t(std::mktime(&tm)).time_since_epoch().count();
-
- return tp;
- }
-
- void writeToFile(net::Message<net::MessageTypes>& msg) {
- std::ofstream file;
- std::stringstream fileName;
- switch(msg.header.id){
- case net::MessageTypes::ServerData:
- fileName << "backup_data_" << session_id << ".log";
- break;
- case net::MessageTypes::ServerLog:
- fileName << "backup_log_" << session_id << ".log";
- break;
- default: break;
- }
-
- file.open(fileName.str(), std::ios_base::app);
- for (auto c : msg.body)
- file << c;
- file.close();
- }
-
-
- int main()
- {
- NetClient c;
- long long lastLog = 0;
-
-
- LOG(INFO) << "press key to connect";
- std::cin.get();
-
- c.Connect("127.0.0.1", 7777);
-
- std::thread keyboardInputThread(readInput);
-
- bool connectionCancelled = false;
-
- while (!connectionCancelled)
- {
- if (c.IsConnected())
- {
- if (!c.Incoming().empty())
- {
- auto msg = c.Incoming().pop_front().msg;
-
- net::Message<net::MessageTypes> messageSend;
- std::string buf = "";
-
- switch (msg.header.id)
- {
- case net::MessageTypes::ServerAlert:
- // Server has responded to a ping request
- LOG(INFO) << "Server Alert notification";
- for (size_t index = 0; index < msg.header.size; index++) {
- buf += msg.body.at(index);
- }
- LOG(INFO) << buf;
- break;
- case net::MessageTypes::ServerAccept:
- // Server has responded to a ping request
- LOG(INFO) << "Server Accepted Connection";
- break;
- case net::MessageTypes::ServerDeny:
- // Server has responded to a ping request
- LOG(INFO) << "Server Denied Connection";
- connectionCancelled = true;
- break;
- case net::MessageTypes::ServerLog:
- // Server has send log data
- LOG(INFO) << "Received Server Log File";
- LOG(INFO) << "Received " << msg.header.size << " Bytes";
- writeToFile(msg);
- lastLog = parseDate(msg);
- break;
- case net::MessageTypes::ServerData:
- LOG(INFO) << "Received Server Data";
- LOG(INFO) << "Received " << msg.header.size << " Bytes";
- writeToFile(msg);
-
- break;
- default: break;
- }
- }
- if (keyboardInput != '0') {
- net::Message<net::MessageTypes> messageSend;
-
- switch (keyboardInput)
- {
- //Log
- case 'l':
- LOG(INFO) << "Request server log files";
- messageSend.header.id = net::MessageTypes::ServerLog;
- messageSend << lastLog;
- c.Send(messageSend);
- break;
- case 'd':
- LOG(INFO) << "Request permanent server data";
- messageSend.header.id = net::MessageTypes::ServerData;
- c.Send(messageSend);
- break;
- case 't':
- LOG(INFO) << "Request temporary server data";
- messageSend.header.id = net::MessageTypes::ServerData;
- c.Send(messageSend);
- break;
- case 'c':
- LOG(INFO) << "Request closing connection";
- messageSend.header.id = net::MessageTypes::ServerCloseConnection;
- c.Send(messageSend);
- break;
- default:
- break;
- }
- keyboardInput = '0';
- }
- }
- else
- {
- LOG(INFO) << "Server Down";
- break;
- }
- }
- LOG(INFO) << "End excution";
-
- return 0;
- }
|