我正在尝试寻找一种惯用且非冗余的方法,以使服务器根据进程启动时给出的某些命令行选项使用不同的处理程序来读写套接字。这很简单,但是我试图在main()
函数中创建一个与命令行选项相对应的类的实例,并在我的处理程序中引用该特定实例。例如,考虑以下代码片段。
PlainServer.hpp
:
class PlainServer : public TCPServer {
public:
typedef std::vector<uint8_t> PlainDatabase;
typedef uint64_t PlainQuery;
typedef std::vector<uint8_t> PlainReply;
explicit PlainServer(aio::io_context& io_context);
PlainReply generate_reply(PlainQuery query);
void gen_database();
private:
PlainReply reply_;
std::unique_ptr<PlainDatabase> db_;
ServerConfig server_config_;
// NOTE: server takes over ownership of db and frees it when it exits.
// Caller cannot free db
void set_database(std::unique_ptr<std::vector<uint8_t>> &&db);
};
PIRServer.hpp
:可以认为与上面的PlainServer
类似,但是方法和类型定义将有所不同和特定。此外,方法将比PlainServer
中列出的方法更多。因此,我认为我不能仅使用基类和多态性来消除某些冗余。
TCPServer.hpp
:(注意:aio
是我所说的boost::asio
)
class TCPServer {
public:
explicit TCPServer(aio::io_context &io_context);
private:
aio::io_context& io_context_;
tcp::acceptor acceptor_;
class TCPConnection : public boost::enable_shared_from_this<TCPConnection> {
public:
typedef boost::shared_ptr<TCPConnection> pointer;
static pointer create(aio::io_context& io_context);
tcp::socket& socket();
void start();
private:
tcp::socket socket_;
std::string message_;
explicit TCPConnection(aio::io_context &io_context);
void handle_read_echo(const boost::system::error_code&, size_t);
void handle_write_echo(const boost::system::error_code&, size_t);
// void handle_read_plain(const boost::system::error_code&, size_t);
// void handle_write_plain(const boost::system::error_code&, size_t);
// void handle_read_pir(const boost::system::error_code&, size_t);
// void handle_write_pir(const boost::system::error_code&, size_t);
};
void accept_new();
void handle_accept(
TCPServer::TCPConnection::pointer& new_connection,
const boost::system::error_code& error);
};
TCPServer.cpp
:
TCPServer::TCPServer(aio::io_context& io_context)
: io_context_(io_context),
acceptor_(io_context, tcp::endpoint(tcp::v4(), server_config.port)) {
// Begin listening for incoming connections
accept_new();
}
void TCPServer::accept_new() {
// Create a pointer to a new TCPConnection object
TCPConnection::pointer conn = TCPConnection::create(io_context_);
acceptor_.async_accept(conn->socket(),
boost::bind(&TCPServer::handle_accept,
this, conn, aio::placeholders::error));
}
void TCPServer::handle_accept(
TCPServer::TCPConnection::pointer& conn,
const boost::system::error_code& error) {
std::cout << "[+] New connection: " << conn->socket().local_endpoint()
<< " (local) <---> " << conn->socket().remote_endpoint()
<< " (remote)" << std::endl;
if (!error) {
conn->start();
}
TCPServer::accept_new();
}
TCPServer::TCPConnection::TCPConnection(aio::io_context &io_context) : socket_(io_context) {}
TCPServer::TCPConnection::pointer TCPServer::TCPConnection::create(aio::io_context& io_context) {
return pointer(new TCPConnection(io_context));
}
tcp::socket& TCPServer::TCPConnection::socket() {
return TCPConnection::socket_;
}
void TCPServer::TCPConnection::start() {
aio::async_read_until(socket_,
aio::dynamic_buffer(message_), "\n",
boost::bind(&TCPConnection::handle_read_echo,
shared_from_this(),
aio::placeholders::error,
aio::placeholders::bytes_transferred));
}
void TCPServer::TCPConnection::handle_read_echo(const boost::system::error_code& err, size_t) {
// TODO: error check and guard the user input
if (!err) {
// async_write handles serializing the data for the socket
aio::async_write(socket_,
aio::buffer(message_),
boost::bind(&TCPConnection::handle_write_echo,
shared_from_this(),
aio::placeholders::error,
aio::placeholders::bytes_transferred));
message_.clear();
} else {
delete this;
}
}
void TCPServer::TCPConnection::handle_write_echo(const boost::system::error_code& err, size_t) {
if (!err) {
aio::async_read_until(socket_,
aio::dynamic_buffer(message_),"\n",
boost::bind(&TCPConnection::handle_read_echo,
shared_from_this(),
aio::placeholders::error,
aio::placeholders::bytes_transferred));
} else {
delete this;
}
}
因此,基本上,我希望能够根据用户是否输入特定的命令行参数而在TCPServer
中调用不同的处理程序,并且这些处理程序应引用在{{1中创建的}}(因为我想通过main()
获得db_
属性)。我对如何构造它感到很困惑。
在此先感谢您的帮助。