Использование boost :: asio :: async_read не работает, но boost :: asio :: read работает (я использую io_stream.run_one ()) - PullRequest
2 голосов
/ 09 декабря 2011

У меня есть собственный сокет posix, который я пытаюсь асинхронно прочитать с помощью boost :: asio :: async_read. Однако, когда я делаю это:

// io_stream and fd are passed by reference to this function
asio::posix::stream_descriptor stream(io_stream);
stream.assign(fd);

boost::system::error_code ec;

asio::async_read(stream, buffer,
                 asio::transfer_at_least(1),
                 boost::bind(doRead,
                             asio::placeholders::error,
                             asio::placeholders::bytes_transferred));
size_t count = io_service.run_one(ec);

Переменная count установлена ​​в 0, обработчик doRead никогда не вызывается, и ec не содержит ошибок. Однако, если я заменю асинхронное чтение синхронным чтением:

size_t count = asio::read(stream, buffer,
                          asio::transfer_at_least(1));

Это работает, и я получаю ожидаемое количество данных обратно в переменную count.

Мои тестовые случаи с использованием fd, созданного "int pipe (int pipefd [2])"; и передача данных через эту работу нормально с asio :: async_read, поэтому я думаю, что это может быть несколько вариантов:

  • Некоторые данные о том, что собственный дескриптор, который я передаю, каким-то образом не совместимы с async_read, поэтому он молча терпит неудачу. Я пытался создать его с блокировкой вкл / выкл безрезультатно.
  • io_service и posix :: stream_descriptor - некоторые из них, так как они не связаны, поэтому io_service никогда не пытается запустить чтение. Может ли это быть из-за того, что я передал io_service по ссылке? (И в течение нескольких потоков, если на то пошло?)

1 Ответ

1 голос
/ 12 декабря 2011

Я обнаружил проблему.

Я вызывал io_service.stop () в функции инициализации объекта-владельца, так как он может быть повторно инициализирован.Однако я не вызывал io_service.reset () после вызова stop, и io_service не будет запускаться после остановки до тех пор, пока не будет вызван сброс.

Урок в RTFM, как остановки, так и сброса, документируют это.

Однако переменная boost :: system :: error_code не отражала это состояние, что немного расстраивает, так как это избавило бы меня от необходимости возиться.

...