I am trying to make a REASON API server that will accept requests from another application, but the problem is that after the first connection to it, it shuts down with the error -1073741819. When I went through it with the debugger, I found out that the error is called buffer_ "An unhandled exception was caused: a violation of read access.this was 0xffffffffffffffffff.", but I do not know how to solve this problem
cpp.file
-------------------
#include "Server.h"
using namespace boost::asio;
namespace beast = boost::beast;
namespace http = beast::http;
using tcp = boost::asio::ip::tcp;
Server::Server(boost::asio::io_service& io_service, int port)
: acceptor_(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)),
socket_(io_service) {
StartAccept();
}
void Server::StartAccept() {
acceptor_.async_accept(socket_, [this](boost::system::error_code ec) {
if (!ec) {
std::cout << "Client connected" << std::endl;
ReadRequest();
}
else {
std::cerr << "Client error: " << ec.message() << std::endl;
}
});
}
void Server::ReadRequest() {
buffer_.consume(buffer_.size());
buffer_.prepare(1024);
beast::http::async_read(socket_, buffer_, request_,
[this](boost::system::error_code ec, size_t bytes_transferred) {
if (!ec) {
ProcessRequest();
}
else {
std::cerr << "Error ReadRequest: " << ec.message() << std::endl;
}
});
}
void Server::ProcessRequest(){
if (request_.method() == http::verb::get) {
http::response<http::string_body> response(http::status::ok, request_.version());
response.set(http::field::server, "Boost Beast Server");
response.set(http::field::content_type, "text/plain");
response.keep_alive(request_.keep_alive());
response.body() = "Hello, World";
response.prepare_payload();
WriteResponse(response);
}
else {
http::response<http::string_body> response(http::status::bad_request, request_.version());
response.set(http::field::server, "Boost Beast Server");
response.set(http::field::content_type, "text/plain");
response.keep_alive(request_.keep_alive());
response.body() = "Invalide request!";
response.prepare_payload();
WriteResponse(response);
}
}
void Server::WriteResponse(boost::beast::http::response<boost::beast::http::string_body>& response_){
http::async_write(socket_, response_,
[this](boost::system::error_code ec, size_t byte) {
if (ec) {
std::cerr << "Error WriteResponse: " << ec.message() << std::endl;
}
StartAccept();
});
}
h.file
---------------
#include <iostream>
#include <boost/asio.hpp>
#include <boost/beast.hpp>
#include <string>
class Server {
public:
Server(boost::asio::io_service& io_service, int port);
private:
void StartAccept();
void ReadRequest();
void ProcessRequest();
void WriteResponse(boost::beast::http::response <boost::beast::http::string_body>& response_);
boost::asio::ip::tcp::acceptor acceptor_;
boost::asio::ip::tcp::socket socket_;
boost::beast::flat_buffer buffer_;
boost::beast::http::request<boost::beast::http::string_body> request_;
};
The error originates in serializing the response.
You can tell by the assert happening in debug mode:
gdb tells us the place:
The reason is that the response is passed by reference to an async operation. Fix it e.g. by making it a member or using the type-erasing
message_generatorutilityShowing the latter:
Live On Coliru
The output of test:
being
I suggest looking at the Beast async http server examples for more good practices!
UPDATE/BONUS
Also showing concurrent connections separating
ServerfromSessionand in the process reducing the includes in the header file:Live On Coliru
File
server.hFile
server.cpp