/
isachkov
/
crypto_server
Обзор
Документация
Войти
/
isachkov
/
crypto_server
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/client.cpp
98 строк
3 KB
Ivan Sachkov
Fix comment
15 май 2024, 20:42
15 май 2024, 20:42
86762d7
Код
Авторство
О чём код?
#include <crypto_chat/client.hpp> #include <unistd.h> #include <iostream> Client::Client(Executor& executor, SSLProvider& provider) : exec_{executor}, secure_layer_(provider.make_ssl_instance()) {} Client::~Client() { if (socket_ > 0) { close(socket_); } } void Client::set_server_location(std::string address, std::string port) { address_ = std::move(address); port_ = std::move(port); } bool Client::connect() { if(!location_) { return false; } auto server_socket = socket(location_->ai_family, location_->ai_socktype, location_->ai_protocol); if (server_socket == -1) { return false; } socket_ = server_socket; return ::connect(socket_, location_->ai_addr, location_->ai_addrlen) == 0; } int Client::run() { // 1. Resolve server address auto server_location = resolve(address_.c_str(), port_.c_str()); if(!server_location) { return EXIT_FAILURE; } location_ = std::move(server_location); // 2. Connect to the server, before switching the socket into async processing const auto connected = connect(); if (!connected) { std::cerr << "Could not connect to the server: " << address_ << " port: " << port_ << '\n'; return EXIT_FAILURE; } // 3. Egress path, sends user input to the secure layer const auto input_added = exec_.on_read(STDIN_FILENO, [this](auto buffer) { secure_layer_.send(std::move(buffer)); }); if(!input_added) { return EXIT_FAILURE; } // 4.1. Egress path, send encoded data to the server // Prod-grade solution require to manage EAGAIN here with adding EPOLLOUT routine, but // in the illustration project it's not necessary secure_layer_.on_encrypted([this](auto buffer) { send(socket_, buffer.data(), buffer.size(), 0); }); // 5. Ingress path, receives other chat partisipant's messages from the server const auto server_added = exec_.on_read(socket_, [this](auto buffer) { secure_layer_.receive(std::move(buffer)); }); if(!server_added) { return EXIT_FAILURE; } // 5.1. Ingress path, decode participant's message secure_layer_.on_decrypted([](auto buffer){ std::cout << std::string(buffer.begin(), buffer.end()); }); // 6. Init secure layer const auto secure_status = secure_layer_.init(false); if(!secure_status) { std::cerr << "Could not init secure layer!\n"; return EXIT_FAILURE; } // 7. Handle server's disconnection exec_.on_disconnect([this](auto) { std::cout << "Server has terminated the connection\n"; exec_.stop(); }); // 8. Run async event queue, emplementing our IO-based logic // // Production-grade solution should employ epoll_pwait with the signal masking // inside the "run" method, but I've ommited signal handling for overall // brevity exec_.run(); return EXIT_SUCCESS; }