Планирование задачи в Boost при продолжении текущей работы - PullRequest
0 голосов
/ 08 июня 2011

Я написал программу TCP / IP, в которой клиент использует обычный (не Boost) API сокетов;т.е. сервер связывает и слушает, а клиент подключается.Сервер использует pthreads для обработки нескольких клиентов одновременно.

Программа использует OpenSSL для обмена ключами сеанса между клиентом и сервером.

Позже я заметил, что периодически мне нужно выполнять«Повторный ключ»: после того, как сеанс установлен, я должен запланировать задачу повторного ключа, в которой клиент и сервер согласовывают новый ключ сеанса.

Один вариант заключался в создании новогопоток для каждого клиента: новый поток будет находиться в режиме ожидания в течение некоторого времени, а затем пробуждается и инициирует повторное нажатие.Этот вариант довольно дорогой, поскольку каждый клиент должен быть многопоточным.

Другой вариант заключался в использовании Boost Asio.Я сожалею, что не знал, что эта ценная библиотека существовала;в противном случае я бы закодировал программу, используя потоки Boost и сокеты Boost.

В любом случае, я хочу выполнить работу с минимальными изменениями.Сначала я неправильно понял Asio.Используя пример Boost's Timer 2 , я написал что-то вроде этого:

void rekey(const boost::system::error_code& /*e*/)
{
  // do rekey
}

...

void main()
{
//connect to server

// schedule re-key
boost::asio::io_service io;    
boost::asio::deadline_timer t(io, boost::posix_time::minutes(30));
t.async_wait(rekey);    
io.run();

// the rest of job (i.e. sending and receiving messages in a while() loop.)
}

Это явно неправильно, так как Boost блокирует на io.run().Мое первое восприятие состояло в том, что асинхронная природа async_wait решит проблему, но, очевидно, я неправильно понял модель Asio.

Я имею в виду два решения:

  1. Генерация функциив котором выполняется отправка и получение (с использованием обычного API сокета), и добавьте эту функцию в очередь объекта io, чтобы io.run() работал как положено.
  2. Переписать функции сокета с помощью Boost'sAPI асинхронного сокета.

Есть ли лучшее решение?В любом случае, не могли бы вы помочь мне понять, как реализовать лучшее решение?

Ответы [ 2 ]

2 голосов
/ 08 июня 2011

Как правило, io_service::run() (или другие функции, которые вызывают события, такие как io_service::poll(), io_servive::run_one() и io_service::poll_one()) будут запускаться в своем собственном потоке.

Я являюсьБольшой сторонник библиотеки boost :: asio, поскольку, как только вы привыкли к ее кодированию, это очень элегантная и мощная библиотека.Однако, если у вас уже есть большая часть написанного (и работающего) приложения, я бы не предложил переписывать его просто для того, чтобы воспользоваться преимуществами boost :: asio, особенно если вам нужен только какой-то тип асинхронного таймера.

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

1 голос
/ 09 июня 2011

Переписать функции сокетов с помощью API асинхронного сокета Boost.

Это может быть не такой сложной задачей, как может показаться.Документация включает в себя хорошее сопоставление API сокета BSD с Boost.Asio.

...