boost :: asio :: async_read_until Не обрезать входное сообщение - PullRequest
0 голосов
/ 01 апреля 2020

Я пытаюсь усечь входное сообщение, когда программа прочитала указанный c символ, для этого у меня есть следующий код:

Это ActiveSocketClientConnection.h

class ActiveSocketClientConnection : public boost::enable_shared_from_this<ActiveSocketClientConnection>{
private:

    boost::shared_ptr<tcp::socket> socket_;
    boost::asio::streambuf data_;

    ...

public:

    ...
}

Это ActiveSocketClientConnection. cpp

void ActiveSocketClientConnection::handleConnect(const boost::system::error_code& error){

    std::string sETX;
    sETX.push_back(0x3A); //0x3A = :

    boost::asio::async_read_until(
        *socket_.get(),
        data_, 
        sETX.c_str(),
        boost::bind(&ActiveSocketClientConnection::handleReadBody,
            this,
            boost::asio::placeholders::error
        )
   );
}

void ActiveSocketClientConnection::handleReadBody(  boost::system::error_code error){
    size_t t = data_.size();

    unsigned char* output = (unsigned char*)malloc(t);
    memcpy(output, boost::asio::buffer_cast<const void*>(data_.data()), t);

    data_.consume(t);

    ...
}

Если я передаю сообщение (например) AA: A с сокетным соединением. Функция async_read_until сохраняет все сообщения в data_ , не усекает сообщение, в котором присутствует символ : .

Кто-то может сказать мне, что я делаю не так?

Спасибо.

1 Ответ

0 голосов
/ 01 апреля 2020

Во-первых, у вас неопределенное поведение. Вы звоните async_read_until с std::string_view в качестве разделителя. Но это представление создается на основе std::string, который является локальным внутри вашей функции дескриптора. async_read_until немедленно заканчивается, строка как локальная уничтожается, и у вас есть свисающий указатель в представлении строки (std::string_view не делает глубокую копию строки, это просто пара: указатель на данные и их размер).

Как решение только вызов перегрузка взятие char

boost::asio::async_read_until(
    *socket_.get(),
    data_, 
    0x3A,  // <- added
    boost::bind(&ActiveSocketClientConnection::handleReadBody,
        this,
        boost::asio::placeholders::error
    )

);


1014 * Официальные ссылка подталкивание состояния:

После успешной операции async_read_until динамическая буферная последовательность c может содержать дополнительные данные помимо разделителя . Приложение обычно оставляет эти данные в динамической буферной последовательности c для последующей операции async_read_until для проверки.

Таким образом, вам необходимо проанализировать данные в поисках первого вхождения разделителя и извлечь собственно суббуфер прочитанных данных.

...