从asio :: async_write接收几个字符

时间:2019-04-18 09:26:44

标签: c++ boost-asio

我正在通过TCP / IP呼叫服务器。我要发送几个字符,并希望收到我的acknowledge-fct发送的答案。但是我只收到发送到服务器的字符数。


constexpr int maxInputBufferLength{1024};

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


struct session
   : public std::enable_shared_from_this<session>
{

public: 
    session(tcp::socket socket)
        : socket_(std::move(socket))
    {
    }

    void start(){
        do_read();
    }

private:
    void do_read(){
        auto self(shared_from_this());
        socket_.async_read_some(boost::asio::buffer(data_, maxInputBufferLength),
                [this, self](boost::system::error_code ec, std::size_t length)

        {
            command_t currentCommand{data_};
            if(currentCommand.commandStringVector.front()==driveCommand){
                acknowledge("driveCommand triggered by TCP");
            }
            ....

    }

    void acknowledge(std::string ackmessage){
        auto self(shared_from_this());
        boost::asio::async_write(socket_, boost::asio::buffer(ackmessage, maxInputBufferLength),
                [this, self, ackmessage](boost::system::error_code ec, std::size_t length)
                {
                    std::cout << ackmessage <<"\n";
                    if(ec.value()){
                        std::cerr << ec.category().name() << ':' << ec.value() << "\n";
                    }
                });
    }

    char data_[maxInputBufferLength];

};

据我所知,我的acknowledge函数以自己的async_write调用boost::asio::buffer的函数应发送整个缓冲区,该缓冲区应包含长度为{的ackmessage {1}}是全局maxInputBufferLength

1 个答案:

答案 0 :(得分:2)

您有未定义的行为,因为您将局部变量传递到buffer中。 buffer仅是字符串的包装,可以视为一对:指向数据和数据大小的指针,它不复制ackmessage 。您需要确保ackmessage存在,直到调用async_write的处理程序为止。 async_write立即返回,所以您现在的样子如下:

acknowledge ()
{
    ackmessage // local variable
    async_write is called, it creates buffer to askmessage, pointer to string is stored
    // async_write returns immediately
    // ackmesssage is destroyed here
}

修复:

1)考虑使用同步写入操作

2)如果您想使用 async ,则可以将ackmessage存储为session的数据成员,然后将其作为参数传递给buffer。您需要找到延长其生存期的方法,直到调用处理程序为止。

Here是解决您的问题,从shared_ptr创建ackmessage并将其传递给您的处理程序lambda的好例子-lambda,它延长了正在写入的字符串的寿命。