![]() |
|
Модераторы: feodorv |
![]()
|
|
| Kirgston |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 792 Регистрация: 24.12.2007 Репутация: нет Всего: 2 |
Мда... увы но не додумался. К сож. справка буста далеко не такого качества как МСДН =) а я привык чтобы все в деталях было. А тут ,как по мне, то оно переводится как удаленная конечная точка, собственно что мне не говорит о том что это сокет =) . Ладно высказал своё "фи", хотя если либы которые намного(!) хуже описаны =) . Хардкор одним словом =)) ТТЛ это первое что пришло в голову Спасибо большое =). Очень не привычно что тут весь буст связан между собой. Жаль правда что , опять таки, мануал не шибко хорош. Собственно выдержка из доков:
Увы там ни слова нету что надо передавать кол-во входящих параметров и конечно же ни слова о том что надо передать еще boost::asio::placeholders::error :( . Ладно, не важно =)) разобрался уже =)). Спасиб большое! Но думаю вопросов еще будет много |
||||
|
|||||
| Kirgston |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 792 Регистрация: 24.12.2007 Репутация: нет Всего: 2 |
Опять таки прошу Вашей помощи... как нормально закрыть сессию клиента? о_О
При вызове деструктора я фактически получаю аксес виолешен. Причем деструктор вызывается не 1 раз... :( причем подряд :( |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 13 Всего: 110 |
естественно первый: второй: а что за проблема с закрытием сессии - не понял. |
|||
|
||||
| Kirgston |
|
||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 792 Регистрация: 24.12.2007 Репутация: нет Всего: 2 |
boostcoder, Собственно на сколько я понял там надо использовать умные указатели. Т.к. можно удалить класс а на самом деле еще внутри ядра буста (а именно асио) висит эвент для него, или нечто похожее. Так что я делал shared_from_this().reset; По крайней мере c delete this точно ничего не вышло
Собственно те старые проблемы решил. Но теперь мой мозг взрывает одна, на первый взгляд, мелочь. Дело в том что сделал таймер для каждой сессии. По истечению таймера идет разрыв связи и удаление класса (ну некий примитивный антифлуд). Оно всё работает (проверяли). Только когда начали проверять на реальном клиенте то оказалось что ничего не работает. А точнее таймер вылетает с ошибкой. Точнее вызывается мой евент для таймера . Ошибка "Операция ввода/вывода была прервана из-за завершения потока команд или по запросу приложения" и код ошибки 995. Перед этим идет отправка данных. Но я уже пробовал её убирать - бесполезно. Таймаут вызывается, грубо говоря, в точный промежуток времени. То есть не когда попадая а именно после некоторой ф-ции. Только увы кроме отправки данных (которую я так же убрал) там ничего и нету. Вот собственно как у меня таймер настраивается:
Собственно данная ф-ция вызывается всякий раз когда пришел пакет. Хотя у меня и не так много пакетов приходит... всего 3 =) Может проблема в указателях ... поэтому выкладываю еще и метод управления с помощью них: Главная часть:
Кусочек сесии: (там много лишнего поетому всё и не выкладывал)
Все указатели у меня в виде shared_from_this() . Может их не правильно сделал? |
||||||
|
|||||||
| boostcoder |
|
||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 13 Всего: 110 |
во первых - это не рационально. обычно подобное реализуется при помощи единственного контейнера состояний, каждый элемент которого, содержит, помимо прочего, переменную содержащую время последней активности. я для этого использую time_t, полученный от time(). так вот... раз в 10 секунд(такой у меня таймаут для определения что клиент тупит/висит), проверяем все временные метки, и ту, которая превысила таймаут - удаляем. этой задачей у меня занимается класс sheduler, который помимо описанного, еще и занимается рассылкой новостей, обновлением статистики в клиентской программе, банера, чата, и всякой ерундой.
это, пожалуйста еще раз, без эмоций ;) зы код сейчас гляну... Добавлено @ 00:02 член какого класса? Добавлено @ 00:04
тут дважды создаете объект сессии. используйте второй способ ;) Добавлено через 6 минут и 49 секунд в хэндлерах, в else-блоках, сделайте вывод в консоль, или в лог. в остальном ничего критичного не заметил. Добавлено через 8 минут и 57 секунд из конструктора и деструктора объекта сессии, тоже сделайте вывод. это позволит видеть моменты создания и удаления сессий. Добавлено через 10 минут и 28 секунд в данной модели сессии, так и должно быть. Добавлено через 12 минут и 10 секунд в примере, конструктор сессии был приватным, если не ошибаюсь. это для того, чтоб объекты сессии создавались только при помощи ее статической функции create() Это сообщение отредактировал(а) boostcoder - 2.3.2011, 00:04 |
||||
|
|||||
| Kirgston |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 792 Регистрация: 24.12.2007 Репутация: нет Всего: 2 |
совершенно согласен. Но как тогда? Создавать тот же вектор или список с указателями на классы и скажем раз в 10 секунд пробегаться по всем существующим классам? Просто вызывается OnTimeOut
в котором error != NULL, а собственно и произошла где то ошибка. Почему? знать не знаю :(. Собственно код ошибки приводил выше. session опс... банальная очепятка. Второй и используется. Первый закоментирован П.С. добавил файлик который отвечает за обработку. Собственно в нем все и проблемы. Буду очень признателен если посмотрите! Это сообщение отредактировал(а) Kirgston - 3.3.2011, 08:40 |
|||
|
||||
| boostcoder |
|
||||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 13 Всего: 110 |
угу. это все же лучше чем по таймеру на каждого юзера. при том, в моем варианте, sheduler занимается ищи всякой другой работой, так же, без дополнительный таймеров. никогда не сравнивал boost::system::error_code с NULL. но подозреваю, что происходит сравнение с нулем. достаточно просто if ( error ) { значит есть ошибка } посмотрю. Добавлено через 2 минуты и 27 секунд в начале файла есть такое:
скажите, в реальном коде все так же? Добавлено через 8 минут и 30 секунд в session, убери все строчки: shared_from_this().reset(); рекомендую почитать: http://www.boost.org/doc/libs/1_46_0/libs/..._from_this.html и задуматься над смыслом применения reset() к результату shared_from_this() Добавлено через 10 минут и 26 секунд
не нужно такого делать. почитайте все же приведенную мною ссылку. |
||||||
|
|||||||
| boostcoder |
|
||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 13 Всего: 110 |
есть такой метод:
далее его вызов таким образом:
угадайте, на что указывает аргумент AsyncWrite() после выхода из SCConnectResultSend() ? ;) далее, еще 6 раз повторяется та же ошибка. в общем, проще переписать с нуля. Добавлено через 2 минуты и 56 секунд не забываем про спасибо ;) Это сообщение отредактировал(а) boostcoder - 2.3.2011, 00:40 |
||||
|
|||||
| Kirgston |
|
||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 792 Регистрация: 24.12.2007 Репутация: нет Всего: 2 |
Да, подозреваю что сейчас меня закидают тухлыми яйцами и помидорами По сути shared_from_this() это и есть *this , если конечно я правильно понял. Просто в одном, уже, горе примере видел такое:
Собственно линк: http://alexott.net/common/asio-notes/test-otpc-conn.cpp.html Вот я и...
Читал... просто буст достаточно велик и не всё сразу понимаю =)), тогда так? shared_from_this()->Stop(); . Тогда что, все вызовы с этого же класса (this) переделать в shared_from_this() ?
Честно , хоть убейте не понимаю...
Собственно мы же сначала берем адрес а потом ставим на этот адрес указатель на unsigned char. Вроде всё законно . Да и размер нормально передается. Или опять таки shared_from_this()->AsyncWrite ? Хотя не шибко понимаю... ведь shared_from_this() указывает на this... или я не прав? Может, но для начала лучше понять как правильно писать |
||||||||
|
|||||||||
| boostcoder |
|
||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 13 Всего: 110 |
да, запихни в класс. переменные, которые доступны нескольким сессиям, и которые могут изменяться, защити от промежуточного состояния. про бложек уже писал ;) shared_from_this() создает новый смарт-поинтер на this, тем самым инкрементируя счетчик ссылок. применяя к результату вызова shared_from_this(), reset() - происходит декрементирование. т.е. смысла в этом выражении ноль! после выхода из SCConnectResultSend(), указатель, указывает в никуда ;) size - да, содержит правильный размер только потому, что он передается по значению. в общем решается это так:
Добавлено через 13 минут и 45 секунд Up. Это сообщение отредактировал(а) boostcoder - 2.3.2011, 09:32 |
||||
|
|||||
| Kirgston |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 792 Регистрация: 24.12.2007 Репутация: нет Всего: 2 |
А как тогда удалить класс ? =))) вручную останавливать все коллбеки , закрывать всё всё всё и потом delete this? O_o
Ну... и да и нет =). Почему? Говорю только то что вижу =). Собственно когда вызывается this->AsyncWrite(pMsg); деструктор, грубо говоря, функции еще не вызван. И те объекты еще живут. Насколько я понимаю (конечно я могу и заблуждаться). Данные объекты не видны за пределами этой ф-ции. Но ведь где то в памяти для них выделено место, верно? И если есть права записи\чтения из этой области то я думаю что спокойно можно поставить указатель. Конечно, если поставить брейкпоинт на AsyncWrite то в data будет только первый символ. Но я предполагаю что там так же идет нечто типа memcpy(buf,(void*)&data,len); или что то такое. Т.к. я проходился сниффером пакетов и там четко видно что все пакеты приходят именно "как надо" =). То есть полностью. Значит внутри всё норм? Правда для теста сейчас вообще удалю AsyncWrite и забабахаю отправку в каждой ф-ции. Быдлокод конечно... но что поделать? надо же понять почему таймер так начинает сбоить... (хотя если честно то у меня и на одном коннекте он сбоит... ) |
|||
|
||||
| boostcoder |
|
||||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 13 Всего: 110 |
объект сам удалится ;) когда вызываешь - да. но когда выходишь из SCConnectResultSend(), на что они указывают? ;) а так как ты вызываешь асинхронную операцию, она вернет управление сразу, а реальная запись данных произойдет несколько позже. потому в доке и говорится:
нет. данные находятся на стеке, и валидны до выхода из блока. бессмысленное занятие, правда. Добавлено через 3 минуты и 23 секунды вот конкретный пример из доки:
даже название функции соответствующее ;) Это сообщение отредактировал(а) boostcoder - 2.3.2011, 09:45 |
||||||
|
|||||||
| Kirgston |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 792 Регистрация: 24.12.2007 Репутация: нет Всего: 2 |
Хм.. тогда надо вызвать socket_.shutdown + socket_.close? Или просто socket_.shutdown ? Кстати... вот эти умные указатели... они же наверно кучу ресурсов жрут? =) Да, что то не подумал... увы Собственно создал шаблон, но мучают сомнения что он опять крив
т.к. опять таки указатель на память... но как иначе? Мне ведь надо как то структуру переделать в набор данных. Или еще до вызова AsyncWrite переделать в UCHAR и повесить умный указатель? Не увидел Очень извиняюсь, просто уже путаться начал |
|||
|
||||
| boostcoder |
|
||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 13 Всего: 110 |
при разрушении объекта сессии, сокет закроется в любом случае, потому что он является членом сессии. не то чтобы много...но жрут. смарт-поинтер передаваемый в шаблон, передай его дальше в хэндлер. это: так:
правильно, это делается при помощи сериализации ;) |
||||
|
|||||
| Kirgston |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 792 Регистрация: 24.12.2007 Репутация: нет Всего: 2 |
Само собой. Но если напрямую нельзя вызвать delete this из-за возможных побочных эффектов, тогда как? Ага, с этим уже раз работал =) правда я так юникод передавал =)) чтобы не заморачиватся с разбиением и переделываем юникода в массив тех же UCHAR использовал сериализацию. Кстати тогда Вы тоже помогли с примером Добавлено через 14 минут и 20 секунд По сути на счет дисконнекта и разрушения объекта я имею такие предположения: 1) delete this . Но кажется что это чревато. Класс удалится, но в ядре асио может остаться коллбек или что то такое на выделенную область памяти под класс. В итоге акксес виолейшен 2) socket_.close \ socket_.shutdown . Я не знаю как работает асио внутри... но при дисконекте вызванном самим клиентом то автоматически разрушается и класс. Вот собственно и появилась мысля... что если разорвать связь то автоматически и закроется класс 3) shared_from_this().reset . Вроде оно освобождало... ну по крайней мере рамка прыгала с 8мб до 5 и обратно =). Хотя могу ошибаться... Собственно вот такие вот мысли ... а что из этого верно? =) извините за тупость, просто пока только учусь и множество вещей понимаю именно с видимого результата и чисто своих предположений |
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Сети | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |