2012-06-15 2 views
2

Я хочу сообщение с состоянием, но не похоже на пример эхо-сервера boost. Мой сокет будет готов для чтения навсегда, и всякий раз, когда он получает новые данные, он будет вызывать виртуальный метод dataAvailable(string), однако он может делать async_write в любое время.boost asio stateful socket interface

void connected(const boost::system::error_code &ec) { 
    _socket.async_read_some(boost::asio::buffer(_buffer, max_length), 
     boost::bind(&Session::handler_read, this, boost::asio::placeholders::error, 
     boost::asio::placeholders::bytes_transferred)); 
    //boost::asio::async_read(_socket, boost::asio::buffer(_buffer, max_length), 
    // boost::bind(&Session::handler_read, this, boost::asio::placeholders::error, 
    // boost::asio::placeholders::bytes_transferred)); 
    std::cout << ">> Session::connected()" << std::endl; 
} 

void handler_read(const boost::system::error_code &ec, size_t bytes_transferred) { 
    if(ec) { 
    std::cout << ec.message() << std::endl; 
    } else { 
    //std::copy(_buffer, _buffer+bytes_transferred, data.begin()); 
    std::string data(_buffer, _buffer+bytes_transferred); 
    std::cout << ">> Session[ " << id() << "]" << "::handler_read(): " << 
      bytes_transferred << " " << data << std::endl; 
    boost::asio::async_write(_socket, boost::asio::buffer(_buffer, max_length), 
      boost::bind(&Session::handler_write, this, 
      boost::asio::placeholders::error)); 
    _socket.async_read_some(boost::asio::buffer(_buffer, max_length), 
      boost::bind(&Session::handler_read, this, boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 
    //boost::asio::async_read(_socket, boost::asio::buffer(_buffer, max_length), 
     // boost::bind(&Session::handler_read, this, 
     // boost::asio::placeholders::error, 
     // boost::asio::placeholders::bytes_transferred)); 
     //call dataAvailable(_buffer); 
    } 
} 

void handler_write(const boost::system::error_code &ec) { 
    if(ec) { 
    std::cout << ec.message() << std::endl; 
    } else { 
    _socket.async_read_some(boost::asio::buffer(_buffer, max_length), 
      boost::bind(&Session::handler_read, this, boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 
    //boost::asio::async_read(_socket, boost::asio::buffer(_buffer, max_length), 
     // boost::bind(&Session::handler_read, this, 
     // boost::asio::placeholders::error, 
     // boost::asio::placeholders::bytes_transferred)); 
    } 
} 
  1. ли это реализация Хорошо? поскольку несколько потоков могут выполнять операции чтения и записи. где в операции записи Updation некоторых клеток в матрице
  2. Почему он не работает (не эхо это принимаемый строка), когда я использую async_read вместо async_read_some
  3. В моем прослушивания сервера я нигде вызывающий метод listen , но все же его работа. Тогда почему есть метод прослушивания? и когда он используется?
  4. Я хочу получить уведомление, когда клиентский сокет выходит со стороны клиента. например Клиент закрыл соединение. Как мне это сделать ? Я, как правило, читаю End Of File в read_handler Но это единственный способ?
  5. У меня есть класс Session, и каждый сеанс имеет один сокет. Я храню Session* colection в диспетчере сеансов. теперь, когда я закрываю сокет и delete, этот сеанс становится нулевым. и это может произойти в середине vector. Итак, как безопасно удалить эту сессию null?
+0

Можете ли вы отредактировать свой вопрос с помощью [автономного репродуктора] (http://sscce.org/), чтобы мы могли видеть, как он не работает? В фрагменте кода, который вы опубликовали, нет ничего очевидного. –

ответ

0

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

  1. появляется сообщение
  2. Do async_write (но это требует времени)
  3. Расписание следующего чтения
  4. Получить следующее сообщение
  5. ли второй async_write (первый еще не завершена, вы получите мусор один другая сторона ссылки)
  6. Расписание следующего чтения
  7. Первый async_write заканчивает и планирует еще один async_read_some

Подводя итог, вы запрашиваете asio для выполнения нескольких операций чтения и записи в один и тот же сокет одновременно.

Почему он не работает (не эхо это принимаемый строка), когда я использую async_read вместо async_read_some

Вы представляемого достаточно данных (max_length)? Может быть, вы хотели бы использовать boost::asio::transfer_at_least(min_length)?

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

Возможно, вы где-то создали объект-акцептор.

Я хочу получить уведомление, когда клиентский сокет выходит со стороны клиента. напримерКлиент закрыл соединение. Как мне это сделать ? Я получаю выход, читая End Of File в read_handler Но это единственный способ?

Вы можете создать обертку, которая займет EOF и выполнить некоторую очистку. Затем вы переносите все пользовательские обработчики с помощью обертки и обертки для переноса в качестве обработчика для boost :: asio. Таким образом, у вас есть только одно место для обработки ошибки EOF, если вы предпочитаете.

У меня есть класс Session, и каждый сеанс имеет один сокет. Я храню сеанс * colection в диспетчере сеансов. теперь, когда я закрываю сокет и удаляю его, этот сеанс становится нулевым. и это может произойти в середине вектора. Итак, как безопасно удалить этот нулевой сеанс?

Использование boost::shared_ptr в обработчиках и так далее и boost::shared_ptr или boost::weak_ptr в векторе Session Manager.