Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Buffers

Boost , Boost.Asio , Core Concepts and Functionality

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

По сути, I/O включает в себя передачу данных в смежные области памяти и из них, называемые буферами. Эти буферы могут быть просто выражены как кортеж, состоящий из указателя и размера в байтах. Однако, чтобы позволить разработку эффективных сетевых приложений, Boost. Asio включает поддержку операций по рассеянию. Эти операции включают один или несколько буферов:

  • Считывание рассеяния принимает данные в несколько буферов.
  • Собирательная запись передает несколько буферов.

Поэтому нам нужна абстракция для представления коллекции буферов. Подход, используемый в Boost. Asio определяет тип (на самом деле два типа), чтобы представлять один буфер. Они могут храниться в контейнере, который может быть передан для операций рассеяния.

Помимо указания буферов в качестве указателя и размера в байтах, Boost. Asio проводит различие между модифицируемой памятью (называемой мутируемой) и немодифицируемой памятью (где последняя создается из хранилища для конст-квалифицированной переменной). Поэтому эти два типа можно определить следующим образом:

typedef std::pair<void*, std::size_t> mutable_buffer;
typedef std::pair<const void*, std::size_t> const_buffer;

Здесь mutable_buffer может быть преобразован в const_buffer, но преобразование в противоположном направлении недействительно.

Тем не менее, буст. Asio не использует приведенные выше определения as-is, а вместо этого определяет два класса: mutable_buffer и const_buffer. Их цель состоит в том, чтобы обеспечить непрозрачное представление смежной памяти, где:

  • Типы ведут себя как std::pair в конверсиях. То есть mutable_buffer конвертируется в const_buffer, но обратное преобразование не допускается.
  • Существует защита от переполнения буфера. В случае буфера пользователь может создать только другой буфер, представляющий тот же диапазон памяти или его поддиапазон. Для обеспечения дополнительной безопасности библиотека также включает механизмы автоматического определения размера буфера из массива, boost::array или std::vector элементов POD, или из std::string.
  • Нарушения безопасности должны быть явно запрошены с использованием функции buffer_cast. В общем, приложение никогда не должно этого делать, но реализация библиотеки требует передать необработанную память основным функциям операционной системы.

Наконец, несколько буферов могут быть переданы операциям рассеяния (таким как read() или write()), помещая буферные объекты в контейнер. Концепции MutableBufferSequence и ConstBufferSequence были определены таким образом, что могут использоваться контейнеры, такие как std::std::list, std::boost::array.

Streambuf for Integration with Iostreams

Класс boost::asio::basic_streambuf получен из std::basic_streambuf для связи входной последовательности и выходной последовательности с одним или более объектами некоторого типа массива символов, элементы которых хранят произвольные значения. Эти объекты решетки символов являются внутренними для объекта streambuf, но прямой доступ к элементам решетки обеспечивается, чтобы они могли использоваться с операциями ввода/вывода, такими как операции отправки или приема розетки:

  • Входная последовательность Streambuf доступна через функцию data(). Тип возврата этой функции соответствует требованиям ConstBufferSequence.
  • Выходная последовательность Streambuf доступна через функцию prepare(). Тип возврата этой функции соответствует требованиям MutableBufferSequence.
  • Данные передаются из передней части выходной последовательности в заднюю часть входной последовательности, вызывая функцию commit().
  • Данные удаляются из передней части входной последовательности, вызывая функцию consume().

Конструктор streambuf принимает аргумент size_t, определяющий максимум суммы размеров входной и выходной последовательности. Любая операция, которая в случае успеха выведет внутренние данные за пределы этого предела, приведет к исключению std::length_error.

Bytewise Traversal of Buffer Sequences

Шаблон класса buffers_iterator<> позволяет пересекать буферные последовательности (т.е. типы, отвечающие требованиям MutableBufferSequence или ConstBufferSequence), как если бы они были смежными последовательностями байтов. Также предоставляются вспомогательные функции, называемые buffers_begin() и buffers_end(), где автоматически выводится параметр шаблона buffers_iterator<>.

В качестве примера, чтобы прочитать одну строку из гнезда и в std::string, вы можете написать:

boost::asio::streambuf sb;
...
std::size_t n = boost::asio::read_until(sock, sb, '\n');
boost::asio::streambuf::const_buffers_type bufs = sb.data();
std::string line(
    boost::asio::buffers_begin(bufs),
    boost::asio::buffers_begin(bufs) + n);
Buffer Debugging

Некоторые стандартные библиотечные реализации, такие как тот, который поставляется с Microsoft Visual C++ 8.0 и более поздней версией, обеспечивают функцию, называемую отладкой итератора. Это означает, что валидность итераторов проверяется во время выполнения. Если программа пытается использовать итератор, который был признан недействительным, будет запущено утверждение. Например:

std::vector<int> v(1)
std::vector<int>::iterator i = v.begin();
v.clear(); // invalidates iterators
*i = 0; // assertion!

Повышаю. Asio использует эту функцию, чтобы добавить отладку буфера. Рассмотрим следующий код:

void dont_do_this()
{
 std::string msg = "Hello, world!";
 boost::asio::async_write(sock, boost::asio::buffer(msg), my_handler);
}

Когда вы вызываете асинхронное чтение или запись, вы должны убедиться, что буферы для операции действительны до тех пор, пока не будет вызван обработчик завершения. В приведенном выше примере буфером является переменная std::string msg. Эта переменная находится в стеке, и поэтому она выходит за рамки до завершения асинхронной операции. Если вам повезет, приложение рухнет, но более вероятны случайные сбои.

Когда буферная отладка включена, Boost. Asio хранит итератор в строке до завершения асинхронной операции, а затем удаляет его, чтобы проверить его валидность. В приведенном выше примере вы бы наблюдали неудачу утверждения непосредственно перед повышением. Азио пытается вызвать обработчика завершения.

Эта функция автоматически становится доступной для Microsoft Visual Studio 8.0 или более поздней версии и для GCC при определении _GLIBCXX_DEBUG. Для этой проверки есть стоимость производительности, поэтому отладка буфера включена только в сборках отладки. Для других компиляторов он может быть включен путем определения BOOST_ASIO_ENABLE_BUFFER_DEBUGGING. Он также может быть явно отключен путем определения BOOST_ASIO_DISABLE_BUFFER_DEBUGGING.

See Also

buffer, buffers_begin, buffers_end, buffers_iterator, const_buffer, const_buffers_1, mutable_buffer, mutable_buffers_1, streambuf, ConstBufferSequence, MutableBufferSequence, buffers example (C++03), buffers example (c++11).


PrevUpHomeNext

Статья Buffers раздела Boost.Asio Core Concepts and Functionality может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Core Concepts and Functionality ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-19 18:17:54/0.0082299709320068/0