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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> boost::asio & async_connect 
:(
    Опции темы
Kirgston
Дата 4.9.2011, 20:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Всем доброго времени суток! Дело такое... есть класс(клиент) который должен асинхронно работать с сервером. Проблема очень странного характера. 

Есть:

Код

    void Connect(char* ip, int port, int Type)
    {
        this->Type = Type;

        socket_.async_connect(this->endpoint,
            boost::bind(&wsJoinServerCli::handle_connect, 
            this,
            boost::asio::placeholders::error));

        SendBytes = 0;
    }


    void handle_connect(const boost::system::error_code& error) 
    {
        if (!error)
        {
            this->socket_.async_receive(boost::asio::buffer(data_, max_length),
            boost::bind(&wsJoinServerCli::handle_read, this,
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred));

            Connected = true;
        }
        else
        {
    
        }
    }


Всё это члены класса wsJoinServerCli. Забавно то что оно работает так сказать через раз. Точнее через неделю. Одну неделю я компилирую код и всё хорошо. На сл. неделю (это всё конечно утрировано и примерно) тот же код без йоты изменений уже не работает. Как только я делаю:

Код

    void Connect(char* ip, int port, int Type)
    {
        this->Type = Type;
        this->endpoint = tcp::endpoint(boost::asio::ip::address::from_string(ip), port);
        socket_.connect(this->endpoint, port);
        Connected = true;
        SendBytes = 0;
    }


Сразу всё начинает работать. А в первом варианте handle_connect попросту не вызывается. Никаких ошибок, никаких проблем. Она просто не вызывается. Вот и сижу уже битые часа 4 и понять не могу. Облазил примеры с буста там примерно всё так же. В чем ошибка понять не могу. А ведь хочется чтобы работал полностью асинхронно =) а не то что в одном месте мы синхронные в другом асинхронны.  smile 

Так же еще один вопрос из разряда "глупости". Интересует как правильно(!) отправлять данные в асинхронном р-ме. А точнее: есть например структура, тут понятно, её просто пакуем в shared_pointer и кидаем в async_send(). А что если не структура? А просто массив еще и неизвестной длинны? Сколотить из него структуру я явно не могу. Длинна узнается прямо перед отправкой. Как тут быть? 
PM MAIL   Вверх
mabrarov
Дата 4.9.2011, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

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



Непонятно, как (кто, когда, чем) в первом варианте заполняется this->endpoint? Действительно ли там всегда содержится что-то вменяемое на момент вызова async_connect? Все это сильно зависит от остального кода.
PM MAIL WWW Skype   Вверх
Kirgston
Дата 4.9.2011, 22:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(mabrarov @  4.9.2011,  22:11 Найти цитируемый пост)
в первом варианте заполняется this->endpoint?

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

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


pattern`щик
****


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

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



Цитата(Kirgston @  4.9.2011,  22:30 Найти цитируемый пост)
Причем в первом случае не просто каллбэка нету а и вообще коннекта.

т.е. ты хочешь сказать, что мало того что коннекта не происходит, так еще и хендлер не вызывается? а если вызывается, то error_code чему равен?

Цитата(Kirgston @  4.9.2011,  20:24 Найти цитируемый пост)
есть например структура, тут понятно, её просто пакуем в shared_pointer и кидаем в async_send().

без сериализации?

Цитата(Kirgston @  4.9.2011,  20:24 Найти цитируемый пост)
А что если не структура? А просто массив еще и неизвестной длинны? Сколотить из него структуру я явно не могу. Длинна узнается прямо перед отправкой. Как тут быть?

поясните...
PM WWW   Вверх
Kirgston
Дата 4.9.2011, 22:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(boostcoder @  4.9.2011,  22:34 Найти цитируемый пост)
т.е. ты хочешь сказать, что мало того что коннекта не происходит, так еще и хендлер не вызывается?

да, именно. Как будто вникуда идет socket_.async_connect(). Само собой кода ошибки не имею


Цитата(boostcoder @  4.9.2011,  22:34 Найти цитируемый пост)
без сериализации?

Угу. Через shared_pointer. Например вот так вот:


Код

    boost::shared_ptr<STRUCT> pResult(new STRUCT);
    AsyncWrite(pResult, pResult->h.size);

    ....

    template<typename T> void AsyncWrite(boost::shared_ptr<T> data, int len)
    {
        socket_.async_send(boost::asio::buffer(data.get(), len),
            boost::bind(&DataSession::handle_write, shared_from_this(),
            boost::asio::placeholders::error));
    }


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


Цитата(boostcoder @  4.9.2011,  22:34 Найти цитируемый пост)
поясните... 

Буст асио он ведь не риал тайм(если не ошибаюсь). И если я создаю локальный(!) буфер в котором формирую список данных и передаю этот буфер в async_send(). Отправка данных понятное дело не моментальная, может отправится через 0.1с а может и через 1с. Но после выхода из блока этот статический буфер само собой уничтожится. В итоге асио попытается отправить те данные которых уже нету, либо на ихнем адресе лежат уже другие данные


Это сообщение отредактировал(а) Kirgston - 4.9.2011, 22:45
PM MAIL   Вверх
boostcoder
Дата 4.9.2011, 23:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(Kirgston @  4.9.2011,  22:43 Найти цитируемый пост)
Как будто вникуда идет socket_.async_connect().

компилятор/ОС/версия_boost ?

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


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

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



Цитата(Kirgston @ 4.9.2011,  22:30)
Причем в первом случае не просто каллбэка нету а и вообще коннекта.

Надо проверить:
  • не закрывается (уничтожается) ли сокет сразу после вызова async_connect
  • как идет работа с соотв. asio::io_service

PM MAIL WWW Skype   Вверх
Kirgston
Дата 4.9.2011, 23:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(boostcoder @  4.9.2011,  23:07 Найти цитируемый пост)
компилятор/ОС/версия_boost ?

MSVC 2010 Sp1
boost 1.47
XP Sp3


PM MAIL   Вверх
Kirgston
Дата 5.9.2011, 08:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



user posted image

Забавно вот что... может я и не на то смотрю. Но тем не менее. Когда делаю:
Код

this->endpoint = tcp::endpoint(boost::asio::ip::address::from_string(ip), port);

Эндпоинт отлично заполняется. Но обратите внимание на то как он заполняется когда я вызываю connect(). Эндпоинт попросту не заполнен

user posted image

Так же чуток забавно с async_connect. State у них разные. Я уже даже не понимаю куда копать :(





Это сообщение отредактировал(а) Kirgston - 5.9.2011, 08:52
PM MAIL   Вверх
boostcoder
Дата 5.9.2011, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



такое предположение: если при использовании connect(), у тебя все работает, потому что каждый раз при его вызове ты заново инициализируешь endpoint, значит, в противном случае, значение endpoint`а который ты используешь для async_connect() чем-то затирается.

попробуй перед каждым async_connect() инициализировать endpoint.
PM WWW   Вверх
Kirgston
Дата 5.9.2011, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(boostcoder @  5.9.2011,  14:22 Найти цитируемый пост)
попробуй перед каждым async_connect() инициализировать endpoint. 

Так вот же на втором скрине видно что он инициализируется перед async_connect(). 

Что 


Код

socket_.async_connect(this->endpoint,
            boost::bind(&wsJoinServerCli::handle_connect, 
            this,
            boost::asio::placeholders::error));


Что


Код

socket_.async_connect(tcp::endpoint(boost::asio::ip::address::from_string(ip), port),
            boost::bind(&wsJoinServerCli::handle_connect, 
            this,
            boost::asio::placeholders::error));


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


pattern`щик
****


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

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



показывай больше кода. а лучше компилябельный код воспроизводящий проблему.

Добавлено через 48 секунд
может то, куда ты коннектишься, тупо висит?
PM WWW   Вверх
mabrarov
Дата 5.9.2011, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

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



Еще раз повторю:
  • раз есть проблемы с самим connect, то, скорее всего, socket разрушается (закрывается) до окончания асинхронной операции;
  • раз есть проблемы с вызовом handler, то это значит, что соотв. io_service уже "не крутится".
Мужики, ну сколько таких проблем описано в asio-users mailing list? И все снова туда же. Весь код в студию! Хотя бы минимальный работающий пример, демонстрирующий проблему.


Это сообщение отредактировал(а) mabrarov - 5.9.2011, 14:46
PM MAIL WWW Skype   Вверх
boostcoder
Дата 5.9.2011, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(mabrarov @  5.9.2011,  14:45 Найти цитируемый пост)
раз есть проблемы с самим connect, то, скорее всего, socket разрушается (закрывается) до окончания асинхронной операции;

я подумал что ТС в курсе что сервер не должен обрывать соединение ;)
PM WWW   Вверх
mabrarov
Дата 5.9.2011, 15:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

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



Цитата(boostcoder @ 5.9.2011,  15:03)
Цитата(mabrarov @  5.9.2011,  14:45 Найти цитируемый пост)
раз есть проблемы с самим connect, то, скорее всего, socket разрушается (закрывается) до окончания асинхронной операции;

я подумал что ТС в курсе что сервер не должен обрывать соединение ;)

Все в курсе. Все (полностью) читали документацию. И все начинают оптимизировать (или просто боятся мифических циклических ссылок) и выкидывают enable_shared_from_this. Наболело. Если не лень - подсчитайте, сколько было аналогичных вопросов в списке рассылки по Asio.

Да, можно обойтись без enable_shared_from_this. Но надо читать доки, где четко описаны требования к времени жизни всех компонент, входящих в асинхронную операцию.

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


 




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


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

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