Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Переполнение очереди BOOST::ASIO 
:(
    Опции темы
orsobruno
Дата 25.1.2011, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 25.1.2011

Репутация: нет
Всего: нет



Есть многопоточный асинхронный сервер на базе примера буст
Код

class server{
  explicit jserver()
  {
          boost::asio::ip::tcp::resolver resolver(io_service_);
          boost::asio::ip::tcp::resolver::query query(address, port);
          boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
          acceptor_.open(endpoint.protocol());
          acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
          acceptor_.bind(endpoint);
          acceptor_.listen();
          acceptor_.async_accept(new_connection_->socket(),
              boost::bind(&jserver::handle_accept, this,
                boost::asio::placeholders::error));
  }
    void handle_accept(const boost::system::error_code& error)
    {
        if (!error)
        {
            new_connection_->start();
            new_connection_.reset(new jconnection(io_service_));
            acceptor_.async_accept(new_connection_->socket(),
                boost::bind(&jserver::handle_accept, this, 
                boost::asio::placeholders::error));
        }
    }
}


далее сам класс соединений c запусками асинхр операций
Код

class jconnection: public boost::enable_shared_from_this<jconnection>, private boost::noncopyable
{
public:
    explicit jconnection(boost::asio::io_service& io_service) 
        : socket_(io_service), strand_(io_service)
    {}

    boost::asio::ip::tcp::socket& socket()
    {
        return socket_;
    }

    void start()
    {
        void (jconnection::*f)(const boost::system::error_code&)= &jconnection::handle_read_header;

        socket_.async_read_some(boost::asio::buffer(inbound_header_),
        strand_.wrap(
            boost::bind(f,shared_from_this(), boost::asio::placeholders::error)) );
    }
    void handle_read_header(const boost::system::error_code& error)
    {
         // что-то делаем, далее стартуют еще асинхронные операции
         }

        // в конце всех операций вызываем
    void close()
    {
        socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
        //socket_.close();
    }

Пример стандартный, но где-то что-то начинает идти не так, потому что при тесте беск циклом синхронных запросов, тест завершается сообщением что невозможно выполнить операцию на сокете, так как очередь переполнена, значит где-то сокет на сервере не закрывается... как это отловить или как увидеть реальное кол-во в очереди находящихся в очереди...
PM MAIL   Вверх
boostcoder
Дата 25.1.2011, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



Цитата(orsobruno @  25.1.2011,  13:09 Найти цитируемый пост)
            new_connection_->start();
            new_connection_.reset(new jconnection(io_service_));

это что? smile 
задумайтесь..

и прочтите про boost::enable_shared_from_this

и еще не понятен смысл:
Цитата(orsobruno @  25.1.2011,  13:09 Найти цитируемый пост)
socket_.shutdown


PM WWW   Вверх
orsobruno
Дата 25.1.2011, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 25.1.2011

Репутация: нет
Всего: нет



Спасибо за ответ.

typedef boost::shared_ptr<jconnection> connection_ptr;

connection_ptr new_connection_;

в конструкторе server ... new_connection_(new jconnection(io_service))

пример взят из boost

принудительное закрытие применяется, когда что-то было не так с трансфером или данными



Это сообщение отредактировал(а) orsobruno - 25.1.2011, 14:43
PM MAIL   Вверх
boostcoder
Дата 25.1.2011, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



мне, конкретно не нравится строка: new_connection_.reset(new jconnection(io_service_));
я никогда не смотрел примеры HTTP, потому никогда не видел такого трюка.
но даже посмотрев, все равно не понимаю надобности в reset..

обычно, модель следующая:
Код

void start_accept() {
   connection::connection_ptr conn = connection::create(io_service);
   _acceptor.async_accept(
      conn->socket(),
      boost::bind(
         &server::on_accept,
         this,
         conn,
         boost::asio::placeholders::error
      )
   );
}

void on_accept(ff_connection::connection_ptr conn, const boost::system::error_code& e) {
   if ( !e ) {
      conn->start();
   }
   start_accept();
}


т.е. созданное соединение запущенно, и живет своей жизнью. и не нужно его трогать smile
в вашем же примере, если я ничего не напутал(что не исключено), после вызова метода start(), происходит удаление _объекта_соединения_. но это не дает ответ на вопрос о утекающих сокетах. это первое.
второе - вы изменили пример взятый из доки? что изменили, и зачем?

Добавлено @ 15:04
изменения вижу в этой строке:
Код

strand_.wrap(
            boost::bind(f,shared_from_this(), boost::asio::placeholders::error))

в оригинале:
Код

strand_.wrap(
        boost::bind(&connection::handle_read, shared_from_this(),
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred)
)

собственно, так же не понимаю надобности... но не в этом суть..

показывайте тело handle_read_header()

Это сообщение отредактировал(а) boostcoder - 25.1.2011, 15:05
PM WWW   Вверх
orsobruno
Дата 25.1.2011, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 25.1.2011

Репутация: нет
Всего: нет



В handle_read_header() идет десериализация заголовка запроса ( inbound_header_ )
и запускается следующий async_read, чтобы читать основное сообщение

Я понимаю, что Вы знаете как сделать правильно, и если я буду все писать, то Вы предложите правильную конструкцию, но так я Вас замучаю.

Давайте остановимся на вопросе, можно ли узнать число коннектов в очереди и я методом мучений постараюсь сам понять?


PM MAIL   Вверх
boostcoder
Дата 25.1.2011, 15:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



Цитата(orsobruno @  25.1.2011,  15:30 Найти цитируемый пост)
можно ли узнать число коннектов в очереди

io_service не предоставляет такой возможности, к сожалению :(

есть подозрение, что у вас не вызывается деструктор jconnection.
впишите в него какой-то вывод, и проверьте, вызывается ли он на самом деле.

второе - деструктор может не вызваться потому, что у jconnection есть незавершенные операции.
поиграйтесь с socket_.close() и socket_.cancel()

ну и отпишитесь о результате. любопытно ведь smile
PM WWW   Вверх
boostcoder
Дата 25.1.2011, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



Цитата(orsobruno @  25.1.2011,  13:09 Найти цитируемый пост)
// в конце всех операций вызываем

а это кстати зачем?
сокет закроется по завершении всех операций, когда разрушится объект jconnection.
по идее, у вас не вызывается деструктор jconnection.
PM WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0717 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.