crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Ошибка bad_weak_ptr, Реализация асинхронного сервера c умными указателями
medhaid
  опции профиля:
сообщение 14.1.2012, 0:07
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 4
Регистрация: 13.1.2012
Пользователь №: 3130

Спасибо сказали: 0 раз(а)




Репутация:   0  


Здравствуйте, не пойму откуда взялась ошибка...

выдается исключение bad_weak_ptr после вызова метода...
socketTCP->async_read_some(boost::asio::buffer(recvBuffer),
boost::bind(&Client::handle_read, this->shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));

//handle_read, handle_write - статическая функция класса Client..
если знаете в чём проблема просьба пояснить почему возникает исключение на моём примере....

#include "ServerTCP.h"

ServerTCP::ServerTCP(boost::asio::io_service &_io_service, int port)
        :acceptor(_io_service, tcp::endpoint(tcp::v4(), port)), io_service(_io_service)
{
    acceptor.listen();

    wait_next_client();
}

ServerTCP::~ServerTCP(void)
{
}

//пришёл запрос на подключение
void ServerTCP::accept_handler(tcp::socket *socket, const boost::system::error_code &error)
{
    if (!error)
    {
        std::cout << "accept" << std::endl;
        new Client(socket);
    }else
    {
        delete socket;
    }

    wait_next_client(); //Запускаем ожидание клиента заново
}

//cоздаём не запушенный сеанс и включаем слушатель
void ServerTCP::wait_next_client()
{
    tcp::socket *socket = new tcp::socket(io_service);

    //начинаем ждать новое подключение
    acceptor.async_accept(*socket, boost::bind(&ServerTCP::accept_handler,
        this, socket, boost::asio::placeholders::error));
}



#include "Client.h"

Client::Client(tcp::socket *_socketTCP)
{
    socketTCP = _socketTCP;

    //информируем
    std::cout << "connect" << std::endl;

    //включаем приём сообшений от клиента
    socketTCP->async_read_some(boost::asio::buffer(recvBuffer),
        boost::bind(&Client::handle_read, this->shared_from_this(),
        boost::asio::placeholders::error,
        boost::asio::placeholders::bytes_transferred));

        //информируем
    std::cout << "connectX" << std::endl;
}

Client::~Client(void)
{
    //информируем
    std::cout << "disconnect" << std::endl;

    //удаляем сокет
    delete socketTCP;
}

//Пришли данные
void Client::handle_read(    boost::shared_ptr<Client> ptr,
                                    const boost::system::error_code& error,
                                    size_t bytes_transferred)
{
    if (error == boost::asio::error::operation_aborted) return;
    if (!error)
    {
        //вывод на консоль инфы
        std::cout << "<read data> size: " << bytes_transferred << std::endl;

        //перезапуск
        /*socketTCP->async_read_some(boost::asio::buffer(recvBuffer),
            boost::bind(&Client::handle_read, ptr,
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred))*/;
    }
    else
    {
        ptr->close();
    }
}

void Client::close()
{
    socketTCP->shutdown(boost::asio::ip::tcp::socket::shutdown_both);
    //socket.close();
}



консоль:
accept
connect
Exception: tr1::bad_weak_ptr
Для продолжения нажмите любую клавишу . . .
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
medhaid
  опции профиля:
сообщение 14.1.2012, 1:00
Сообщение #2


Новичок


Группа: Новичок
Сообщений: 4
Регистрация: 13.1.2012
Пользователь №: 3130

Спасибо сказали: 0 раз(а)




Репутация:   0  


Как дурак пишу вопросы и сам на них отвечаю)))
искал и наконец нашёл решение)))


//перевод с буржуйского форума..
Перед вызовом shared_from_this() ваш класс должен быть сохранен в shared_ptr . Это означает, что вы не можете назвать shared_from_this() внутри конструктора, так как линия объект не будет помещен в shared_ptr пока конструктор закончена.

Именно по этой причине, что классы, которые используют enable_shared_from_this как правило, имеют start функция, которая делает последние шаги инициализации, которые требуют использования shared_from_this() . Это начало функция должна быть вызвана после Объект полностью построен, и поэтому не может быть вызван из внутри конструктора, как вы делаете.



P.S. извиняюсь что создал тему зря....
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 14.1.2012, 11:57
Сообщение #3


Мастер
******

Группа: Модератор
Сообщений: 3290
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


medhaid, всё нормально.
Из этого видно, что ты не бот и думающий программер! Да и наверняка твой ответ кому-нибудь еще пригодится... :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 14.10.2019, 23:09