boost::asio::async_accept 处理程序未被调用

Posted

技术标签:

【中文标题】boost::asio::async_accept 处理程序未被调用【英文标题】:boost::asio::async_accept the handler is not called 【发布时间】:2020-07-18 17:35:06 【问题描述】:

以 boost 为例 https://www.boost.org/doc/libs/1_70_0/doc/html/boost_asio/example/cpp11/ssl/server.cpp

就像组装一样,它就开始工作了。 然后把实现从接口到SSL_Server.h,SSL_Server.cpp,Session.h,Session.cpp,main带到Serv.cpp 结果,处理程序没有被调用!!!不明白是什么原因。

SSL_Server.h

#ifndef SSL_SERVER
#define SSL_SERVER

#define BOOST_ASIO_ENABLE_HANDLER_TRACKING

#include "Session.h"
#include <functional>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>

using boost::asio::ip::tcp;

class SSL_Server

public:
SSL_Server(boost::asio::io_context& io_context, unsigned short port);
private:
void do_accept();
std::string get_password() const;
private:
tcp::acceptor acceptor_;
boost::asio::ssl::context context_;
;
#endif

SSL_Server.cpp

#include "Server_SSL.h"

SSL_Server::SSL_Server(boost::asio::io_context& io_context, unsigned short port)
    : acceptor_(io_context, tcp::endpoint(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(std::bind(&SSL_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");

    do_accept();



std::string SSL_Server::get_password() const

        return "test";


void SSL_Server::do_accept()

    acceptor_.async_accept([this](const boost::system::error_code& error, tcp::socket socket)
    
         if (!error)
         
             std::make_shared<session>(std::move(socket), context_)->start();
         
    );

    

会话.h

#ifndef SESSION
#define SESSION
#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>

using boost::asio::ip::tcp;

class session : public std::enable_shared_from_this<session>

public:
    session(tcp::socket socket, boost::asio::ssl::context& context);

    void start();
private:
    void do_handshake();
    void do_read();
    void do_write(std::size_t length);
private:
    boost::asio::ssl::stream<tcp::socket> socket_;
    char data_[1024];
;

#endif
    

会话.cpp

#include "Session.h"
session::session(tcp::socket socket, boost::asio::ssl::context& context)
    : socket_(std::move(socket), context)



void session::start()

    do_handshake();


void session::do_handshake()

    auto self(shared_from_this());
    socket_.async_handshake(boost::asio::ssl::stream_base::server,
        [this, self](const boost::system::error_code& error)
        
            if (!error)
            
                do_read();
            
        );


void session::do_read()

    auto self(shared_from_this());
    socket_.async_read_some(boost::asio::buffer(data_),
        [this, self](const boost::system::error_code& ec, std::size_t length)
        
            if (!ec)
            
                do_write(length);
            
        );

void session::do_write(std::size_t length)

    auto self(shared_from_this());
    boost::asio::async_write(socket_, boost::asio::buffer(data_, length),
        [this, self](const boost::system::error_code& ec,
            std::size_t /*length*/)
        
            if (!ec)
            
                do_read();
            
        );

    

Serv.cpp

#include "Server_SSL.h"

int main(int argc, char* argv[])

        if (argc != 2)
        
            std::cerr << "Usage: server <port>\n";
            return 1;
        

        boost::asio::io_context io_context;
        SSL_Server s(io_context, 3333);
        io_context.run();

    return 0;

【问题讨论】:

【参考方案1】:

我看不出代码有什么问题。事实上,它对我有用。但是,您需要工作目录中存在的证书、密钥和 DH 参数文件。

我没有看到很多明确的错误处理,所以我想这可能是你的问题:

context_.use_certificate_chain_file("server.crt", ec);
if (ec) throw boost::system::system_error(ec);

context_.use_private_key_file("server.key", boost::asio::ssl::context::pem, ec);
if (ec) throw boost::system::system_error(ec);

context_.use_tmp_dh_file("dh2048.pem", ec);
if (ec) throw boost::system::system_error(ec);

注意

我使用了 boost 示例中的 server.pem 和 dh2048.pem 文件,所以它变成了

context_.use_certificate_chain_file("server.pem", ec);
if (ec) throw boost::system::system_error(ec);

context_.use_private_key_file("server.pem", boost::asio::ssl::context::pem, ec);
if (ec) throw boost::system::system_error(ec);

【讨论】:

以上是关于boost::asio::async_accept 处理程序未被调用的主要内容,如果未能解决你的问题,请参考以下文章

boost::asio async_accept 杀死 ioservice

Boost asio async_accept 在 Windows 下工作,但在 FreeBSD 下失败。怎么了?