Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9ccabcd1eb | |||
| aeeb22d351 | |||
| a4f103d0c8 | |||
| bb99d8d812 | |||
| 1e6fecb7bd | |||
| 88520915dc |
@@ -1,59 +0,0 @@
|
|||||||
#include "echo_client.hpp"
|
|
||||||
#include <boost/asio/connect.hpp>
|
|
||||||
|
|
||||||
EchoClient::EchoClient(IoContext &io, std::string host, unsigned short port)
|
|
||||||
: io_(io)
|
|
||||||
, host_(std::move(host))
|
|
||||||
, port_(port)
|
|
||||||
, socket_(io_)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EchoClient::run(const std::string &message)
|
|
||||||
{
|
|
||||||
if (!connect()) {
|
|
||||||
Logger::error("EchoClient: connect failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const bool ok = send(message);
|
|
||||||
close();
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EchoClient::connect()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
boost::asio::ip::tcp::resolver resolver(io_);
|
|
||||||
auto results = resolver.resolve(host_, std::to_string(port_));
|
|
||||||
boost::asio::connect(socket_, results);
|
|
||||||
Logger::info(
|
|
||||||
"EchoClient: connected to " + host_ + ":" + std::to_string(port_)
|
|
||||||
);
|
|
||||||
return true;
|
|
||||||
} catch (const std::exception &ex) {
|
|
||||||
Logger::error(
|
|
||||||
std::string("EchoClient: connect exception: ") + ex.what()
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EchoClient::send(const std::string &message)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
auto bytes = boost::asio::write(socket_, boost::asio::buffer(message));
|
|
||||||
Logger::info("EchoClient: sent " + std::to_string(bytes) + " bytes");
|
|
||||||
return true;
|
|
||||||
} catch (const std::exception &ex) {
|
|
||||||
Logger::error(std::string("EchoClient: send exception: ") + ex.what());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EchoClient::close()
|
|
||||||
{
|
|
||||||
ErrorCode ec;
|
|
||||||
socket_.shutdown(TcpSocket::shutdown_both, ec);
|
|
||||||
socket_.close(ec);
|
|
||||||
Logger::info("EchoClient: connection closed");
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "aliases.hpp"
|
|
||||||
#include "logger.hpp"
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class EchoClient final
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EchoClient(IoContext &io, std::string host, unsigned short port);
|
|
||||||
|
|
||||||
bool run(const std::string &message);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool connect();
|
|
||||||
bool send(const std::string &message);
|
|
||||||
void close();
|
|
||||||
|
|
||||||
private:
|
|
||||||
IoContext &io_;
|
|
||||||
std::string host_;
|
|
||||||
unsigned short port_;
|
|
||||||
TcpSocket socket_{io_};
|
|
||||||
};
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
#include "echo_client_cli.hpp"
|
|
||||||
#include <boost/program_options/value_semantic.hpp>
|
|
||||||
|
|
||||||
EchoClientCli::EchoClientCli()
|
|
||||||
: CliBase("Echo Client Options")
|
|
||||||
, host_("127.0.0.1")
|
|
||||||
, port_(9000)
|
|
||||||
, message_("Hello from client")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void EchoClientCli::setupOptions()
|
|
||||||
{
|
|
||||||
// clang-format off
|
|
||||||
desc_.add_options()
|
|
||||||
("help,h", "Show help")
|
|
||||||
("host,H", withDefault(host_, "<HOST>"), "Server host (IP or DNS)")
|
|
||||||
("port,p", withDefault(port_, "<PORT>"), "Server port")
|
|
||||||
("message,m", withDefault(message_, "<TEXT>"), "Message to send");
|
|
||||||
// clang-format on
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string EchoClientCli::getHost() const
|
|
||||||
{
|
|
||||||
return vm_.at("host").as<std::string>();
|
|
||||||
}
|
|
||||||
int EchoClientCli::getPort() const
|
|
||||||
{
|
|
||||||
return vm_.at("port").as<int>();
|
|
||||||
}
|
|
||||||
std::string EchoClientCli::getMessage() const
|
|
||||||
{
|
|
||||||
return vm_.at("message").as<std::string>();
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "cli_base.hpp"
|
|
||||||
#include "option_utils.hpp"
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class EchoClientCli : public CliBase, protected OptionUtils
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EchoClientCli();
|
|
||||||
|
|
||||||
std::string getHost() const;
|
|
||||||
int getPort() const;
|
|
||||||
std::string getMessage() const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void setupOptions() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// defaults (used only to show defaults in help via withDefault)
|
|
||||||
std::string host_;
|
|
||||||
int port_;
|
|
||||||
std::string message_;
|
|
||||||
};
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <boost/asio.hpp>
|
|
||||||
#include <boost/program_options.hpp>
|
|
||||||
#include <boost/system/error_code.hpp>
|
|
||||||
|
|
||||||
// --- Error handling ---
|
|
||||||
using ErrorCode = boost::system::error_code;
|
|
||||||
|
|
||||||
// --- IO Context ---
|
|
||||||
using IoContext = boost::asio::io_context;
|
|
||||||
|
|
||||||
// --- TCP ---
|
|
||||||
using TcpSocket = boost::asio::ip::tcp::socket;
|
|
||||||
using TcpAcceptor = boost::asio::ip::tcp::acceptor;
|
|
||||||
using TcpEndpoint = boost::asio::ip::tcp::endpoint;
|
|
||||||
|
|
||||||
// --- UDP (для DNS) ---
|
|
||||||
using UdpSocket = boost::asio::ip::udp::socket;
|
|
||||||
using UdpEndpoint = boost::asio::ip::udp::endpoint;
|
|
||||||
|
|
||||||
// --- Таймеры ---
|
|
||||||
using SteadyTimer = boost::asio::steady_timer;
|
|
||||||
|
|
||||||
// --- Program options ---
|
|
||||||
using OptionsDescription = boost::program_options::options_description;
|
|
||||||
using VariablesMap = boost::program_options::variables_map;
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
#include "cli_base.hpp"
|
|
||||||
#include <boost/program_options/parsers.hpp>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
CliBase::CliBase(const std::string &title)
|
|
||||||
: desc_(title)
|
|
||||||
, help_(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CliBase::parse(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
using namespace boost::program_options;
|
|
||||||
|
|
||||||
setupOptions(); // must be first
|
|
||||||
|
|
||||||
parsed_options parsed = parse_command_line(argc, argv, desc_);
|
|
||||||
store(parsed, vm_);
|
|
||||||
notify(vm_);
|
|
||||||
|
|
||||||
if (vm_.count("help")) {
|
|
||||||
help_ = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CliBase::isHelp() const
|
|
||||||
{
|
|
||||||
return help_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CliBase::printHelp() const
|
|
||||||
{
|
|
||||||
std::cout << desc_ << "\n";
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <boost/program_options/options_description.hpp>
|
|
||||||
#include <boost/program_options/variables_map.hpp>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class CliBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CliBase(const std::string &title);
|
|
||||||
|
|
||||||
virtual ~CliBase() = default;
|
|
||||||
|
|
||||||
// parse argc/argv
|
|
||||||
void parse(int argc, char *argv[]);
|
|
||||||
|
|
||||||
bool isHelp() const;
|
|
||||||
void printHelp() const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// children add their specific options here
|
|
||||||
virtual void setupOptions() = 0;
|
|
||||||
|
|
||||||
boost::program_options::options_description desc_;
|
|
||||||
boost::program_options::variables_map vm_;
|
|
||||||
bool help_;
|
|
||||||
};
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <boost/program_options.hpp>
|
|
||||||
|
|
||||||
class OptionUtils
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
template <typename T>
|
|
||||||
using OptionValue = boost::program_options::typed_value<T> *;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static OptionValue<T>
|
|
||||||
withDefault(const T &value, const char *name = nullptr);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
OptionUtils() = default;
|
|
||||||
~OptionUtils() = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
#include "option_utils.tpp"
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "option_utils.hpp"
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
OptionUtils::OptionValue<T>
|
|
||||||
OptionUtils::withDefault(const T &value, const char *name)
|
|
||||||
{
|
|
||||||
auto v = boost::program_options::value<T>()->default_value(value);
|
|
||||||
if (name) {
|
|
||||||
v->value_name(name); // Optional
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
#include "session_base.hpp"
|
|
||||||
#include "logger.hpp"
|
|
||||||
#include <boost/asio/write.hpp>
|
|
||||||
|
|
||||||
SessionBase::SessionBase(TcpSocket socket)
|
|
||||||
: socket_(std::move(socket))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void SessionBase::start()
|
|
||||||
{
|
|
||||||
doRead();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SessionBase::doRead()
|
|
||||||
{
|
|
||||||
using namespace boost::asio;
|
|
||||||
|
|
||||||
auto self = shared_from_this();
|
|
||||||
|
|
||||||
auto handler = [this, self](ErrorCode ec, std::size_t bytesTransferred) {
|
|
||||||
onRead(ec, bytesTransferred);
|
|
||||||
};
|
|
||||||
|
|
||||||
socket_.async_read_some(buffer(buffer_), handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SessionBase::onRead(ErrorCode ec, std::size_t bytesTransferred)
|
|
||||||
{
|
|
||||||
if (ec) {
|
|
||||||
Logger::error("Read error: " + ec.message());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string rawRequest(buffer_.data(), bytesTransferred);
|
|
||||||
Logger::info("Received request:\n" + rawRequest);
|
|
||||||
|
|
||||||
try {
|
|
||||||
handleRequest(rawRequest);
|
|
||||||
} catch (const std::exception &ex) {
|
|
||||||
Logger::error(std::string("Request handling failed: ") + ex.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SessionBase::doWrite(const std::string &response)
|
|
||||||
{
|
|
||||||
using namespace boost::asio;
|
|
||||||
|
|
||||||
auto self = shared_from_this();
|
|
||||||
auto onWriteHandler =
|
|
||||||
[this, self](ErrorCode ec, std::size_t /*bytesTransferred*/) {
|
|
||||||
if (ec) {
|
|
||||||
Logger::error("Write error: " + ec.message());
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorCode shutdownEc;
|
|
||||||
if (socket_.shutdown(TcpSocket::shutdown_both, shutdownEc)) {
|
|
||||||
Logger::warn("Shutdown error: " + shutdownEc.message());
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorCode closeEc;
|
|
||||||
if (socket_.close(closeEc)) {
|
|
||||||
Logger::warn("Close error: " + closeEc.message());
|
|
||||||
} else {
|
|
||||||
Logger::info("Connection closed");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
async_write(socket_, buffer(response), onWriteHandler);
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "aliases.hpp"
|
|
||||||
#include <array>
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class SessionBase : public std::enable_shared_from_this<SessionBase>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit SessionBase(TcpSocket socket);
|
|
||||||
virtual ~SessionBase() = default;
|
|
||||||
|
|
||||||
void start();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void handleRequest(const std::string_view rawRequest) = 0;
|
|
||||||
|
|
||||||
void doRead();
|
|
||||||
void onRead(ErrorCode ec, std::size_t bytesTransferred);
|
|
||||||
void doWrite(const std::string &response);
|
|
||||||
|
|
||||||
TcpSocket socket_;
|
|
||||||
std::array<char, 8192> buffer_;
|
|
||||||
};
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
#include "tcp_server_base.hpp"
|
|
||||||
#include "logger.hpp"
|
|
||||||
|
|
||||||
TcpServerBase::TcpServerBase(IoContext &io, unsigned short port)
|
|
||||||
: acceptor_(io, TcpEndpoint(boost::asio::ip::tcp::v4(), port))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void TcpServerBase::start()
|
|
||||||
{
|
|
||||||
auto doAccept = [this]() {
|
|
||||||
acceptor_.async_accept([this](ErrorCode ec, TcpSocket socket) {
|
|
||||||
if (!ec) {
|
|
||||||
Logger::info("New client connected");
|
|
||||||
createSession(std::move(socket));
|
|
||||||
} else {
|
|
||||||
Logger::error("Accept error: " + ec.message());
|
|
||||||
}
|
|
||||||
start(); // continue accepting
|
|
||||||
});
|
|
||||||
};
|
|
||||||
doAccept();
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "aliases.hpp"
|
|
||||||
|
|
||||||
class TcpServerBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TcpServerBase(IoContext &io, unsigned short port);
|
|
||||||
virtual ~TcpServerBase() = default;
|
|
||||||
|
|
||||||
void start();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void createSession(TcpSocket socket) = 0;
|
|
||||||
|
|
||||||
TcpAcceptor acceptor_;
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// Alias for raw byte buffer
|
||||||
|
using ByteBuffer = std::vector<std::uint8_t>;
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
// Sequential file chunk index
|
||||||
|
using ChunkIndex = std::uint32_t;
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
// File total size in bytes
|
||||||
|
using FileSize = std::uint64_t;
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
// Wire length prefix type for a single framed message (big-endian on the wire)
|
||||||
|
using FrameLength = std::uint32_t;
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
// Client, group, or message ID
|
||||||
|
using Id = std::uint64_t;
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <boost/asio/io_context.hpp>
|
||||||
|
|
||||||
|
// IO Context
|
||||||
|
using IoContext = boost::asio::io_context;
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <boost/asio/ip/tcp.hpp>
|
||||||
|
|
||||||
|
// TCP
|
||||||
|
using TcpSocket = boost::asio::ip::tcp::socket;
|
||||||
|
using TcpAcceptor = boost::asio::ip::tcp::acceptor;
|
||||||
|
using TcpEndpoint = boost::asio::ip::tcp::endpoint;
|
||||||
|
using TcpResolver = boost::asio::ip::tcp::resolver;
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <boost/asio/steady_timer.hpp>
|
||||||
|
|
||||||
|
// Timers
|
||||||
|
using SteadyTimer = boost::asio::steady_timer;
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <boost/system/error_code.hpp>
|
||||||
|
|
||||||
|
// Error handling
|
||||||
|
using ErrorCode = boost::system::error_code;
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::cout << "Hello, Boost + C++23 + xmake!\n";
|
||||||
|
|
||||||
|
boost::asio::io_context io;
|
||||||
|
boost::asio::steady_timer timer(io, std::chrono::seconds(1));
|
||||||
|
timer.async_wait([](const boost::system::error_code &) {
|
||||||
|
std::cout << "Timer fired after 1 second!\n";
|
||||||
|
});
|
||||||
|
|
||||||
|
io.run();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#include "aliases.hpp"
|
|
||||||
#include "echo_client.hpp"
|
|
||||||
#include "echo_client_cli.hpp"
|
|
||||||
#include "logger.hpp"
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
EchoClientCli cli;
|
|
||||||
cli.parse(argc, argv);
|
|
||||||
if (cli.isHelp()) {
|
|
||||||
cli.printHelp();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger::init(true);
|
|
||||||
|
|
||||||
IoContext io;
|
|
||||||
const std::string host = cli.getHost();
|
|
||||||
const auto port = static_cast<unsigned short>(cli.getPort());
|
|
||||||
const std::string message = cli.getMessage();
|
|
||||||
|
|
||||||
EchoClient client(io, host, port);
|
|
||||||
const bool ok = client.run(message);
|
|
||||||
|
|
||||||
return ok ? 0 : 1;
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#include "aliases.hpp"
|
|
||||||
#include "echo_server.hpp"
|
|
||||||
#include "echo_server_cli.hpp"
|
|
||||||
#include "logger.hpp"
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
EchoServerCli cli;
|
|
||||||
cli.parse(argc, argv);
|
|
||||||
if (cli.isHelp()) {
|
|
||||||
cli.printHelp();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger::init(true);
|
|
||||||
|
|
||||||
IoContext io;
|
|
||||||
const auto port = static_cast<unsigned short>(cli.getPort());
|
|
||||||
EchoServer server(io, port);
|
|
||||||
|
|
||||||
Logger::info("EchoServer starting on port " + std::to_string(port));
|
|
||||||
server.start();
|
|
||||||
|
|
||||||
io.run();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#include "echo_server.hpp"
|
|
||||||
#include "echo_session.hpp"
|
|
||||||
|
|
||||||
void EchoServer::createSession(TcpSocket socket)
|
|
||||||
{
|
|
||||||
auto session = std::make_shared<EchoSession>(std::move(socket));
|
|
||||||
session->start();
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "tcp_server_base.hpp"
|
|
||||||
|
|
||||||
class EchoServer final : public TcpServerBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EchoServer(IoContext &io, unsigned short port)
|
|
||||||
: TcpServerBase(io, port)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void createSession(TcpSocket socket) override;
|
|
||||||
};
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#include "echo_server_cli.hpp"
|
|
||||||
|
|
||||||
EchoServerCli::EchoServerCli()
|
|
||||||
: CliBase("Echo Server Options")
|
|
||||||
, port_(9000)
|
|
||||||
, address_("0.0.0.0")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void EchoServerCli::setupOptions()
|
|
||||||
{
|
|
||||||
// clang-format off
|
|
||||||
desc_.add_options()
|
|
||||||
("help,h", "Show help")
|
|
||||||
("port,p", withDefault(port_, "<PORT>"), "Port to listen on")
|
|
||||||
("address,a", withDefault(address_, "<ADDRESS>"), "Bind address (e.g. 0.0.0.0)");
|
|
||||||
// clang-format on
|
|
||||||
}
|
|
||||||
|
|
||||||
int EchoServerCli::getPort() const
|
|
||||||
{
|
|
||||||
return vm_.at("port").as<int>();
|
|
||||||
}
|
|
||||||
std::string EchoServerCli::getAddress() const
|
|
||||||
{
|
|
||||||
return vm_.at("address").as<std::string>();
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "cli_base.hpp"
|
|
||||||
#include "option_utils.hpp"
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class EchoServerCli : public CliBase, protected OptionUtils
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EchoServerCli();
|
|
||||||
|
|
||||||
int getPort() const;
|
|
||||||
std::string getAddress() const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void setupOptions() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
int port_;
|
|
||||||
std::string address_;
|
|
||||||
};
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#include "echo_session.hpp"
|
|
||||||
#include "logger.hpp"
|
|
||||||
#include <utility> // std::move
|
|
||||||
|
|
||||||
EchoSession::EchoSession(TcpSocket socket)
|
|
||||||
: SessionBase(std::move(socket))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void EchoSession::handleRequest(const std::string_view rawRequest)
|
|
||||||
{
|
|
||||||
Logger::info(
|
|
||||||
std::string("EchoSession received: ") + std::string(rawRequest)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "session_base.hpp"
|
|
||||||
|
|
||||||
class EchoSession final : public SessionBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit EchoSession(TcpSocket socket);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void handleRequest(const std::string_view rawRequest) override;
|
|
||||||
};
|
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "logger.hpp"
|
#include "logger.hpp"
|
||||||
|
|
||||||
#include <boost/date_time/posix_time/posix_time_io.hpp>
|
#include <boost/date_time/posix_time/posix_time_io.hpp>
|
||||||
|
|
||||||
void Logger::init(bool toConsole, const std::string_view filePath)
|
void Logger::init(bool toConsole, const std::string_view filePath)
|
||||||
@@ -2,28 +2,16 @@ set_languages "c++23"
|
|||||||
|
|
||||||
add_rules("plugin.compile_commands.autoupdate", { outputdir = "." })
|
add_rules("plugin.compile_commands.autoupdate", { outputdir = "." })
|
||||||
|
|
||||||
add_requires("cmake::Boost", {
|
add_requires("boost", {
|
||||||
alias = "boost",
|
system = true, -- sudo pacman -S boost
|
||||||
system = true,
|
|
||||||
configs = {
|
configs = {
|
||||||
components = { "program_options", "log" },
|
all = false,
|
||||||
|
system = true, -- asio
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Echo server target
|
target "app"
|
||||||
target "echo_server"
|
set_kind "binary"
|
||||||
do
|
add_files "src/*.cpp"
|
||||||
set_kind "binary"
|
add_links "boost_system"
|
||||||
add_files("src/main/echo_server_main.cpp", "src/server/*.cpp", "src/session/*.cpp", "src/common/*.cpp")
|
|
||||||
add_includedirs("src", "src/server", "src/session", "src/common", { public = true })
|
|
||||||
add_packages "boost"
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Echo client target
|
|
||||||
target "echo_client"
|
|
||||||
do
|
|
||||||
set_kind "binary"
|
|
||||||
add_files("src/main/echo_client_main.cpp", "src/client/*.cpp", "src/session/*.cpp", "src/common/*.cpp")
|
|
||||||
add_includedirs("src", "src/client", "src/session", "src/common", { public = true })
|
|
||||||
add_packages "boost"
|
|
||||||
end
|
|
||||||
|
|||||||
Reference in New Issue
Block a user