boost :: asio async_read не получает данные или не использует обратный вызов - PullRequest
2 голосов
/ 15 октября 2011

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

Код клиента выглядит так:

Client::Client()
{
  m_oIoService.run(); // member boost::asio::io_service
  m_pSocket = new boost::asio::ip::tcp::socket(m_oIoService);

  // Connection to the server
  [...]

  // First read
  boost::asio::async_read(*m_pSocket,
                          boost::asio::buffer((void*)&m_oData, sizeof(m_oData)),
                          boost::bind(&Client::handleReceivedData, this,
                                      boost::asio::placeholders::error,
                                      boost::asio::placeholders::bytes_transferred));
}

Я попытался с небольшими данными (короткая строка), и я не могу заставить его работать. Когда я использую функцию синхронного чтения (boost::asio::read()), используя два одинаковых первых параметра, все работает отлично.

Я что-то упустил при использовании io_service? Я до сих пор не уверен, как это работает.

1 Ответ

5 голосов
/ 15 октября 2011

boost::asio::service::run () - это блокирующий вызов.Теперь, в вашем примере это может или не может вернуться сразу.Если этого не произойдет, вы заблокированы еще до создания сокета и никогда не вызываете read, поэтому не можете ожидать обратного вызова.В противном случае цикл диспетчеризации завершается, поэтому обратные вызовы не доставляются.

Подробнее о boost::asio::service::run ().Я рекомендую вам ознакомиться с документацией , включая учебное пособие, примеры и справочную информацию.Чтобы понять эту концепцию, стоит полностью разобраться.

Надеюсь, это поможет!

PS: Кстати, ваш код не является безопасным для исключений.Помните, что если конструктор класса завершается неудачей с исключением, то деструктор этого экземпляра класса никогда не вызывается.Таким образом, вы можете просочиться как минимум до m_pSocket, если его тип не является одним из «умных указателей».Вам следует подумать о том, чтобы сделать это исключение безопасным, переместить код в другой метод, который должен вызывать пользователь, или даже обернуть эту функцию свободной функцией.

...