【问题标题】:Problems with Async_Read functionAsync_Read 函数的问题
【发布时间】:2015-07-23 19:36:51
【问题描述】:

简介

我正在研究c++和boost/asio实现分布式系统,所以我需要创建一个异步tcp服务器。 服务器的工作方式类似于 echo-server,但您需要先发出请求(例如,通过套接字发送文本),然后服务器只响应 pi 号。

主服务器类中使用的 TCP 连接类

class tcp_connection
    : public boost::enable_shared_from_this <tcp_connection> {
        public:
            typedef boost::shared_ptr<tcp_connection> pointer;

            static pointer create(boost::asio::io_service &io_service){
                return pointer(new tcp_connection(io_service));
            }

            tcp::socket &socket(){
                return socket_;
            }

            void start(){
                for(;;){

                    boost::asio::async_read(socket_, boost::asio::buffer(buffer_),
                        boost::bind(&tcp_connection::handle_read, shared_from_this(),
                         boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)
                    );

                    buffer_ = "Pi: 3.1415\n\0";
                    boost::asio::async_write(socket_, boost::asio::buffer(buffer_),
                        boost::bind(&tcp_connection::handle_write, shared_from_this(),
                            boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
                }
            }
        private:
            tcp_connection(boost::asio::io_service &io_service)
                : socket_(io_service){
            }

            void handle_write(const boost::system::error_code& /*error*/,
                size_t /*bytes_transferred*/){
            }

             void handle_read(){
            }

            //attr
            tcp::socket socket_;
            std::string buffer_;
    };

问题

我在 stackoverflow 中阅读了一些教程和许多问题。我不明白为什么我有这个错误:error: ‘void (tcp_connection::*)()’ is not a class, struct, or union type。

我在这一行找到了错误源:boost::asio::async_read(...)。如果我删除该行,服务器可以正常工作,但我需要了解 async_read 功能以便稍后实现复杂系统。

【问题讨论】:

    标签: c++ boost tcp boost-asio


    【解决方案1】:

    您的async_read 需要一个处理程序——当从套接字读取某些内容时将调用该函数。这个处理程序应该有一个特定的签名。在您的情况下,它应该类似于

    void handle_read(boost::system::error_code const& ec, size_t bytes_transferred)
    

    只是因为你把它当作

    boost::bind(&tcp_connection::handle_read, shared_from_this(),
                         boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)
    

    因此,您将tcp_connection::handle_read 与this(类型)(任何非静态方法的第一个隐式参数)以及错误代码和传输的字节数绑定,因此预期的签名是void handle_read(boost::system::error_code const&amp; ec, size_t bytes_transferred)。也许您需要了解更多关于binding 的工作原理:http://www.boost.org/doc/libs/1_58_0/libs/bind/doc/html/bind.html

    作为奖励:

    你的

    for (;;) 
    {
        //read
        // write
    }
    

    是同步方法。如果你想使用异步,你需要一些不同的东西。主要思想是将它们链接起来,以便您的读取采用处理程序,并且处理程序异步写入响应采用写入处理程序,并且写入处理程序启动另一个异步读取,并如此循环。

    【讨论】:

    • 一个更美妙的“线性”想法:Coroutines
    • 好的,首先,和以前一样的问题,但是现在用你的handle_write,你绑定它的方式和handle_read一样,但是它的签名不同,你看到问题了吗?而bind 真的是老派的方法,如果你的编译器支持 lambdas 更好地使用它们,或者检查 Anno 建议的 Coroutines ^^ 还有其他问题,例如使用您的缓冲区,检查此示例如何正确完成:boost.org/doc/libs/1_58_0/doc/html/boost_asio/example/cpp03/…
    • Asio 的作者有一篇很棒的博客文章 illustrates bind。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-23
    • 2020-11-06
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    • 2011-02-22
    相关资源
    最近更新 更多