Непрерывное повышение :: Asio читает - PullRequest
2 голосов
/ 29 октября 2010

Я экспериментирую с Boost :: asio и пытаюсь создать клиент, который читает и выводит консольные пакеты, отправленные с сервера. Сервер использует проприетарный протокол. Он отправляет обновление таймера каждую секунду, отвечает на команду ping и может ответить списком файлов, когда клиент запрашивает его. Я хорошо разбираюсь в асинхронных сетях, но у меня проблема. Вот код:

class JReader
{
public:
  JReader(boost::asio::io_service &io_s)
    : socket_(io_s)
  {
    tcp::resolver resolver(io_s);
    tcp::resolver::query query("xxxx", "yyyy");
    tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
    tcp::resolver::iterator end;

    boost::system::error_code error = boost::asio::error::host_not_found;
    while (error && endpoint_iterator != end)
    {
      socket_.close();
      socket_.connect(*endpoint_iterator++, error);
    }
    if (error)
    {     
      throw boost::system::system_error(error);
    }


    boost::asio::async_write(socket_, boost::asio::buffer(connect, 12), boost::bind(&JReader::handle_write, this));
    boost::asio::async_write(socket_, boost::asio::buffer(getlist, 3), boost::bind(&JReader::handle_write, this));

    boost::asio::async_read(socket_, boost::asio::buffer(buf_, BUF_SIZE), boost::bind(&JReader::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
  }
private:

  void handle_read(const boost::system::error_code err, size_t bytes)
  {        
    std::cout<<std::endl<<std::string(buf_, bytes);
    boost::asio::async_read(socket_, boost::asio::buffer(buf_, BUF_SIZE), boost::bind(&JReader::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
  }

  void handle_write()
  {
    //TODO: finish this!
    std::cout<<std::endl<<"Wrote something";

  }

  static const int BUF_SIZE = 256;
  char buf_[BUF_SIZE];
  tcp::socket socket_;
};

Программа читает с сервера и выводит данные на консоль - но материнская плата издает ужасный звуковой сигнал. Я почти уверен, что это как-то связано с моим циклом handle_read.

Каков правильный, неблокирующий способ постоянного прослушивания сервера?

Ответы [ 2 ]

4 голосов
/ 29 октября 2010

Ах, ха! Я использовал asio правильно, но моя ошибка заключалась в потоковой передаче двоичных данных в std :: cout !! Вместо этого я использовал файловый поток, и теперь он работает. :)

2 голосов
/ 29 октября 2010

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

Эта операция реализована в виде нуля или более вызовов функции async_write_some потока и известна как составная операция. Программа должна гарантировать, что поток не выполняет никаких других операций записи (таких как async_write, функция async_write_some потока или любые другие составные операции, которые выполняют запись), пока эта операция не завершится.* Скорее всего, вы наблюдаете правильное поведение, потому что отправляемые данные очень короткие (12 и 3 байта соответственно).Я предлагаю опубликовать второй async_write после вызова обработчика для первого.

...