C++简单的http服务器,程序在第二次请求时关闭并且不发送字符串的内容

问题描述 投票:0回答:1

这就是我的 fileCollector 的样子,它只是存储文件的“缓存”(这样您就不会在每个请求期间读取文件)

class FileCollector
    {
    public:
        FileCollector();
        std::string get_file_data(std::string s);
    private:
        std::map<std::string, std::string> fileData;
    };

错误很可能就在这里,但由于缺乏经验,我找不到它。

http_connection::http_connection(tcp::socket socket, std::shared_ptr<Collector::FileCollector> fc)
        : socket_(std::move(socket)),
        filecollector(fc)
    {}

    void http_connection::start(void)
    {
        read_request();
    }

    void http_connection::read_request(void)
    {
        auto self = shared_from_this();

        http::async_read(
            socket_,
            buffer_,
            request_,
            [self](beast::error_code ec,
                std::size_t bytes_transferred)
            {
                boost::ignore_unused(bytes_transferred);
                if(!ec)
                    self->process_request();
            }
        );
    }

    void http_connection::process_request(void)
    {
        response_.version(request_.version());
        response_.keep_alive(false);

        switch (request_.method())
        {
            case (http::verb::get):
                response_.result(http::status::ok);
                response_.set(http::field::server, "Beast");
                create_response();
                break;
            default:
                response_.result(http::status::bad_request);
                response_.set(http::field::content_type, "text/plain");
                beast::ostream(response_.body())
                    << "Invalid request-method '"
                    << std::string(request_.method_string())
                    << "'";
                break;
        }
        write_response();
    }

    void http_connection::create_response(void)
    {
        std::string_view sv = request_.target().substr(1);
        std::string targetfile = {sv.data(), sv.size()};
        
        beast::ostream(response_.body())
            << filecollector->get_file_data(targetfile);
    }

    void http_connection::write_response(void)
    {
        auto self = shared_from_this();
        response_.content_length(response_.body().size());
        http::async_write(
            socket_,
            response_,
            [self](beast::error_code er, std::size_t bytes_trans)
            {
                self->socket_.shutdown(tcp::socket::shutdown_send, er);
            }
        );
    }

我开始联系的方式

void ownHTTPServer::start_acceptor(tcp::acceptor& accepter, tcp::socket& sock,
    std::shared_ptr<Collector::FileCollector> &fc)
{
    accepter.async_accept(sock,
        [&](beast::error_code er){
            if (!er)
            {
                std::make_shared<ownHTTPServer::http_connection>
                    (std::move(sock), std::move(fc))->start();
            }
            start_acceptor(accepter, sock, fc);
        });
}

g++ -IC: oost\include oost-1_84 -lws2_32 -lwsock32 ... 编译器 x86_64-w64-mingw32

如果不使用 filecollector 并且响应内容是 const char*,则代码可以工作

如果对某人来说不困难,我想阅读有关 boost.asio 如何工作的文章

c++ boost server asio
1个回答
0
投票

start_acceptor()
中,每次接受新客户端时,您都会创建一个新的
http_connection
对象,并将fc对象的所有权移动(不是
共享
)到该连接中,因此
fc
失去访问权限到内存中的
FileCollector
对象,使其不再可供后续连接使用。

您永远不应该使用

std::move()
来转让
std::shared_ptr
的所有权,这违背了 共享 所有权的全部意义。

© www.soinside.com 2019 - 2024. All rights reserved.