从 asio::async_write 接收到几个字符

Receiving to few chars from asio::async_write

本文关键字:几个 字符 async asio write      更新时间:2023-10-16

我正在通过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函数使用自己的boost::asio::buffer调用async_write应该发送整个缓冲区,其中应该包含长度为maxInputBufferLengthackmessage,这是一个全局constexpr int

你有未定义的行为,因为你将局部变量传递到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(如果你想保持异步,你可以ackmessage存储为session的数据成员,然后将其作为参数传递给buffer。您需要找到某种方法来延长其生存期,直到调用处理程序。

这里有一个很好的示例来解决您的问题,从ackmessage创建shared_ptr并将其传递给您的处理程序 - lambda,它延长了正在写入的字符串的生存期。