Я пытаюсь создать https-сервер на основе сокетов и распределить его по разным потокам. Сам сервер работает нормально, стабильно удерживает нагрузку и обрабатывает запросы, если все идет в одном потоке. Если я ставлю его в разные потоки, то при тестировании под нагрузкой (wrk) сервер вылетает ... Мой код:
#include <cstdio>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <boost/thread.hpp>
#include <cstdlib>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <iostream>
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket;
class session
{
public:
session(boost::asio::io_context& io_context,
boost::asio::ssl::context& context)
: socket_(io_context, context)
{
}
ssl_socket::lowest_layer_type& socket()
{
return socket_.lowest_layer();
}
void start()
{
socket_.async_handshake(boost::asio::ssl::stream_base::server,
boost::bind(&session::handle_handshake, this,
boost::asio::placeholders::error));
}
void handle_handshake(const boost::system::error_code& error)
{
if (!error)
{
socket_.async_read_some(boost::asio::buffer(data_, max_length),
boost::bind(&session::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
delete this;
}
}
int req_rah = 0;
void handle_read(const boost::system::error_code& error,
size_t bytes_transferred)
{
if (!error)
{
std::string Result_test = "HTTP/1.1 200 OK\r\n" +
std::string("Content-Length: 2\r\n") +
std::string("Content-Type: text/html\r\n") +
std::string("Connection: Closed\r\n\r\n") +
std::string("ok") +
std::string("\r\n");
boost::asio::streambuf request_test;
std::ostream request_stream_test(&request_test);
request_stream_test << Result_test;
boost::asio::write(socket_, request_test);
boost::asio::async_write(socket_,
request_test,
boost::bind(&session::handle_write, this,
boost::asio::placeholders::error));
}
else
{
delete this;
}
}
void handle_write(const boost::system::error_code& error)
{
if (!error)
{
socket_.async_read_some(boost::asio::buffer(data_, max_length),
boost::bind(&session::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
delete this;
}
}
private:
ssl_socket socket_;
enum { max_length = 6291456 };
char data_[max_length] = "";
};
class server
{
public:
server(boost::asio::io_context& io_context, unsigned short port)
: io_context_(io_context),
acceptor_(io_context,
boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)),
context_(boost::asio::ssl::context::sslv23)
{
context_.set_options(
boost::asio::ssl::context::default_workarounds
| boost::asio::ssl::context::no_sslv2
| boost::asio::ssl::context::single_dh_use);
context_.set_password_callback(boost::bind(&server::get_password, this));
context_.use_certificate_chain_file("Server.crt");
context_.use_private_key_file("Server.key", boost::asio::ssl::context::pem);
context_.use_tmp_dh_file("dh2048.pem");
start_accept();
}
std::string get_password() const
{
return "";
}
void start_accept()
{
session* new_session = new session(io_context_, context_);
acceptor_.async_accept(new_session->socket(),
boost::bind(&server::handle_accept, this, new_session,
boost::asio::placeholders::error));
}
void handle_accept(session* new_session,
const boost::system::error_code& error)
{
if (!error)
{
new_session->start();
}
else
{
delete new_session;
}
start_accept();
}
private:
boost::asio::io_context& io_context_;
boost::asio::ip::tcp::acceptor acceptor_;
boost::asio::ssl::context context_;
};
int main(int argc,
char *argv[],
char *envp[])
{
try
{
boost::asio::io_context io_context;
boost::thread_group pool;
server s(io_context, 8080);
for (auto i = 0u; i<boost::thread::hardware_concurrency(); ++i)
pool.create_thread([&] {io_context.run(); });
pool.join_all();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
при доступе из браузера https://127.0.0.1: 8080 все норм я получаю "ок." При выполнении wrk все вылетает ... Как я понимаю, потоки обрабатываются некорректно (чтение или / и ответ), кто бы ни сталкивался с подобной задачей, помогите пожалуйста, что не так ... Заранее спасибо!