Чтение данных из COM-порта — Переполнение буфераC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Чтение данных из COM-порта — Переполнение буфера

Сообщение Anonymous »


I have a problem processing packets from the COM port. This port reads at a speed of 115200. A lot of data from this port is lost. The buffer overflows almost immediately. In the code I attach, I try to remove the overprocessed buffer on the fly.

void COM::ReadLoop(std::shared_ptr pbuf) { if (!pbuf) { assert(m_readoperation.expired()); // do not post overlapping read operations pbuf = std::make_shared(); m_readoperation = pbuf; } asio::async_read(m_port, asio::dynamic_buffer(*pbuf), asio::transfer_at_least(1), [this, pbuf](boost::system::error_code ec, size_t /*length*/) { if (!ec) { auto& buffer = *pbuf; size_t const length = buffer.size(); if (length > 1024) { g_logger.info("buffer overflow"); buffer.erase(buffer.begin(), buffer.begin() + length - 1024); } m_Data.store(length); size_t i = 0; while (i < buffer.size() - 2) { if (buffer == 170 && buffer[i + 1] == 170) { size_t len = buffer[i + 2]; if (len < 4 || len >= 170 || i + 3 + len > buffer.size()) { i++; //We move the index to continue searching continue; } std::vector packetData(buffer.begin() + i + 3, buffer.begin() + i + 3 + len); parse_packet(packetData); buffer.erase(buffer.begin(), buffer.begin() + i + 3 + len); i = 0; previousSize = buffer.size(); } else { i++; } if (buffer.size() == previousSize) { // If the buffer has not been modified, we continue processing // This prevents infinite looping when there is no more data to process break; } } ReadLoop(pbuf); } else { g_logger.info("ReadLoop error: " + ec.message()); } }); } void COM::parse_packet(const std::vector& data) { if (data.size() < 4) // Minimal packet length check return; int generated_checksum = 0; for (size_t i = 0; i < data.size() - 1; ++i) { // Omit the checksum byte in calculations generated_checksum += data; } generated_checksum = 255 - (generated_checksum % 256); int checksum = data.back(); // Assume the last byte is the checksum if (checksum != generated_checksum) { return; // Checksum mismatch } int i = 0; while (i < data.size() - 1) { unsigned char data_type = data[i++]; g_logger.info(std::to_string(data_type)); switch (data_type) { g_logger.info(std::to_string(data_type)); case 1: { unsigned char battery_level = data[i++]; m_BatteryLevel.store(battery_level); break; } // here case 2-5 case 0x80: { // Raw data i += 2; // We ignore the byte length int raw_data = data[i++] = 32768) { raw_data -= 65536; } m_Raw.store(raw_data); } case 0x83: { // Power std::vector g_power; std::ostringstream oss; for (int j = 0; j < 8; ++j) { int power = data[i + 2] + (data[i + 1]

Источник: https://stackoverflow.com/questions/780 ... r-overflow
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»