Версия для печати темы
Форум на CrossPlatform.RU _ boost _ Ошибки при асинхронных опирациях asio
Автор: Гость_Алексей_* 28.12.2011, 15:21
Проблема наверн стандартная, но нормального решения её я не смог нагуглить.
Примерчик обычный... после подключения сессия начинает ждать данные сервер создаёт ещё одну и ждёт пока не придёт подключение.... запускается сессия методом start....
#include "Session.h"
int session_count = 0;
Session::Session(boost::asio::io_service &io_service): socket(io_service)
{
session_count++;
}
Session::~Session(void)
{
//socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both); //не даём создавать новые асинхронные кел беки
//socket.close(); //закрываем соединение
session_count--;
}
//возрашяет сокет
boost::asio::ip::tcp::socket& Session::getSocket()
{
return socket;
}
//Запуск сессии(происходит когда клиент присоединился)
void Session::start()
{
//включаем приём сообшений от клиента
socket.async_read_some(boost::asio::buffer(recvBuffer),
boost::bind(&Session::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
//Пришли данные
void Session::handle_read(const boost::system::error_code& error, size_t bytes_transferred)
{
if (!error)
{
//отправка пакета обратно
socket.async_write_some(boost::asio::buffer("Hello client"),
boost::bind(&Session::handle_write, this,
boost::asio::placeholders::error));
//перезапуск
socket.async_read_some(boost::asio::buffer(recvBuffer),
boost::bind(&Session::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
delete this;
}
}
//Данные отправлены
void Session::handle_write(const boost::system::error_code& error)
{
if (!error)
{
//обработка
//.....................
}
else
{
delete this;
}
}
когда я удаляю сессию в очереди остаются асинхронные операции... которые в итоге роняют сервер...
я пробовал просто закрыть сокет... или вызывать кансел для сокета... но сервер всё равно падает.
читал под линукс всё отработает норм после вызова кансел......
как быть под виндой?
Автор: BRE 28.12.2011, 16:42
Цитата(Гость_Алексей_* @ 28.12.2011, 16:21)
как быть под виндой?
И под вендой, и под linux, я бы не пользовался конструкцией:
delete this;
Если хочешь, что бы объекты Session разрушались сами используй boost::enable_shared_from_this.
Автор: Гость_Алексей_* 28.12.2011, 16:54
Цитата(BRE @ 28.12.2011, 16:42)
Цитата(Гость_Алексей_* @ 28.12.2011, 16:21)
как быть под виндой?
И под вендой, и под linux, я бы не пользовался конструкцией:
delete this;
Если хочешь, что бы объекты Session разрушались сами используй boost::enable_shared_from_this.
Ну как я понимаю через эту чтуку я буду ждать завершения всех асинхронных операций.. а потом тока вызоветься диструктор моего обьекта.
Я хочу найти способ прост обарвать цепочку событий... отменить все асинхронные операции сокета...
отправка и получение данных мне уже не нужна.. когда я добил обьект... иль я чёт непонимаю...
ну за подсказку спасибо.. я какрас копал в эту сторону.
Автор: BRE 28.12.2011, 16:58
Цитата(Гость_Алексей_* @ 28.12.2011, 17:54)
Я хочу найти способ прост обарвать цепочку событий... отменить все асинхронные операции сокета...
socket::shutdown
После этого сработают все callback'и с кодом operation_aborted, при получении этого состояния просто не перезапускай новые обработчики.
Автор: Гость_Алексей_* 28.12.2011, 17:00
Принципе мне неважно, откуда они будут уничтожаться... но я чёт не понимаю, что это даст.
Отловить дисконект я могу ток при записи и чтении... и удалять естественно я должен там после неких действий над объектом.
Автор: Гость_Алексей_* 28.12.2011, 17:05
Цитата(BRE @ 28.12.2011, 16:58)
socket::shutdown
После этого сработают все callback'и с кодом operation_aborted, при получении этого состояния просто не перезапускай новые обработчики.
ну shutdown прост не даст запускать новые.. а те что уже были отправлены до вызова shutdown.
чё с ними.
серовно какбы ждать надо.
Автор: BRE 28.12.2011, 17:10
Цитата(Гость_Алексей_* @ 28.12.2011, 18:05)
ну shutdown прост не даст запускать новые.. а те что уже были отправлены до вызова shutdown.
Про что идет речь? Что не даст запускать?
Автор: Гость_Алексей_* 28.12.2011, 17:31
Цитата(BRE @ 28.12.2011, 17:10)
Про что идет речь? Что не даст запускать?
http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/reference/basic_socket/shutdown/overload1.html
.....This function is used to disable send operations, receive operations, or both.
как я понимаю функция shutdown заставит сокет игнорить вызов асинхронных методов записи и чтения...
Автор: BRE 28.12.2011, 18:00
Цитата(Гость_Алексей_* @ 28.12.2011, 18:31)
как я понимаю функция shutdown заставит сокет игнорить вызов асинхронных методов записи и чтения...
Какого поведения мы хотим от объекта Session?
Как я понял, при определенном состоянии ты хочешь прервать всю обработку и разрушить объект?
Автор: Гость_Алексей_* 28.12.2011, 20:22
Цитата(BRE @ 28.12.2011, 18:00)
Какого поведения мы хотим от объекта Session?
Как я понял, при определенном состоянии ты хочешь прервать всю обработку и разрушить объект?
Ага.)))
Автор: BRE 28.12.2011, 20:48
Цитата(Гость_Алексей_* @ 28.12.2011, 21:22)
Ага.)))
Значит используем boost::enable_shared_from_this в качестве предка Session.
В момент, когда нужно прервать работу и уничтожить объект Session, делаем для сокета shutdown, все активные (уже запущенные обработчики) сработают с error == operation_aborted и при получении этого кода, ты не будешь перезапускать обработчики. Ссылок на объект не останеться и он будет разрушен.
Автор: Гость_Алексей_* 29.12.2011, 10:42
Цитата(BRE @ 28.12.2011, 20:48)
Значит используем boost::enable_shared_from_this в качестве предка Session.
В момент, когда нужно прервать работу и уничтожить объект Session, делаем для сокета shutdown, все активные (уже запущенные обработчики) сработают с error == operation_aborted и при получении этого кода, ты не будешь перезапускать обработчики. Ссылок на объект не останеться и он будет разрушен.
Наверно так и сделаю.
Спасибо BRE за помощь...
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)