2016-04-09 5 views
4

Я недавно писал код для пользовательского протокола последовательной связи. То, что я сделал, я использовал часть (8/16 бит) принимаемых данных, чтобы обозначить, насколько большой размер кадра. Исходя из этих данных, я ожидаю , что нет данных. Я использую Crc для принятия или отклонения кадра. Но я не смогу включить длину кадра данных в Crc, так как на принимающей стороне я должен знать, сколько данных ожидать, до обработки кадра.Как предотвратить переполнение буфера/переполнение массива?

Проблема, с которой я столкнулся, иногда эти данные длины кадра повреждаются, и он обманывает приемник, получая столько байтов, в то время как размер принимающего массива намного меньше. Это искажает множество критических системных переменных, которые присутствуют в последовательных ячейках памяти.

Как предотвратить переполнение буфера? Мои мысли об этом 1) Отклоните данные framelength, если они превышают определенное значение. 2) используйте тип данных, который ограничивает максимальный номер. Подобно использованию короткого замыкания, ограничивающего область индекса массива до 256 мест памяти и создание буфера с 280 байтами. 3) выделяет память в отдельном месте, чтобы она не влияла на критические системные переменные.

Одна вещь, которую я использовал для предотвращения застревания в приемном цикле, - это тайм-аут. Но я не обратил внимания на этот аспект проблемы. Мне кажется, что мне нужно много времени, чтобы подтвердить и воспроизвести проблему, поскольку, таким образом, код является частью более крупного системного кода, и я не эксперт здесь.

Как можно безопасно справляться с такими проблемами?

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

+0

Простите меня, если я неправильно использовал некоторые термины. – seetharaman

+0

Я бы сказал, 2) правильный ответ. (Хотя 'short' - 2 байта, а то, что вы хотите, - это однобайтовое значение.) – user3386109

+0

Я не понимаю, как поврежденные данные длины кадра могут исказить приемник в переполнении буфера. Разумеется, приемник точно считывает количество байтов, которые, как ему сказали, ожидают (или пытается это сделать), и он находится в пределах мощности приемника, чтобы гарантировать, что у него есть достаточный буфер для этого, даже если принятый размер кадра неверен. –

ответ

1

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

Вам необходимо выяснить, что именно подходит для вашей системы. Например, если вы никогда не ожидаете, что сообщение будет больше 256, тогда объявив размер вашего буфера как 0xFF и индекс вашего буфера как uint8_t, вы никогда не сможете превысить его, добавив один байт за раз, поскольку индекс будет никогда не достигает 256 и переполняется до 0. Недостатком этого является, конечно, если это произойдет, вы перезаписываете некоторые из полученных данных, но проверка crc должна выявлять ошибку в большинстве случаев.

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

Чтобы быть честным, лучшим методом является пересмотр вашего пользовательского протокола последовательной связи. Звучит не так, как будто ошибки, с которыми вы сталкиваетесь очень хорошо. Вы можете синхронизировать байты в начале и конце вашего сообщения, чтобы убедиться, что на самом деле вы получаете хорошие данные и CRC для всего сообщения нет проблем и определяете максимальные размеры пакетов данных, которые будут проходить через провод и сигнализировать, сколько пакетов получать. Если протокол связи не очень хорош, вам нужно переосмыслить его снизу вверх.

+0

Я попробую использовать unit8. Я уже использую байты синхронизации в начале кадра. Только после того, как я обнаруживаю байты синхронизации, я получаю данные этого размера кадра. Похоже, что повреждение данных происходит в случайном байте (-ях) в кадре, а остальные байты кажутся прекрасными. – seetharaman

1

первым, проверьте обрамление ошибки, проверьте наличие ошибок четности

во-вторых, проверить величину размера данных. если слишком большой или слишком маленький, отклоните весь блок данных

+0

Я использую заголовок для определения начала кадра и для позиционирования бит. Что касается пары, я не использую UART, поэтому вычисление в SW будет накладным. Проверка размера рамки и отклонения может работать. – seetharaman