Получение нескольких символов из asio :: async_write - PullRequest
0 голосов
/ 18 апреля 2019

Я звоню на сервер через 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 с длиной maxInputBufferLength, который является глобальным constexpr int.

1 Ответ

2 голосов
/ 18 апреля 2019

У вас неопределенное поведение, потому что вы передаете локальную переменную в 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. Вам нужно найти способ продления его времени жизни до вызова обработчика.

Здесь является хорошим примером для решения вашей проблемы, создайте shared_ptr из ackmessage и передайте его вашему обработчику - лямбда, это продлевает время жизни записываемой строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...