| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Сети > [asio] как узнать что произошёл disconnect |
| Автор: borisbn 22.12.2011, 09:44 |
| Всем привет. Есть asio::tcp::socket. Коннекчусь им к серверу. Если сервер выключили или пропало соединение, то как узнать об этом ? И ещё вопросик. Есть ли функция получения текущего состояния сокета - есть коннект / нет коннекта / в процессе коннекта / в процессе дисконнекта ? Спасибо. |
| Автор: borisbn 22.12.2011, 14:01 | ||||||
Вот я и подумал, что туда попадёт только по завершению, а про то, что при разрыве соединения попадёт туда же - не сообразил. Спасибо. Опять же, неправильно понял... Подумал, что эта функция говорит, была ли вызвана ф-ция секета open(), а не "есть ли в данный момент коннект". 2-е спасибо. Раз уж про open() зашла речь, не подскажешь, нужно ли вообще её вызывать ? Зачем она нужна ? В описании очень скупо сказано
В бустовских примерах её никто не вызывает...
Ессно прочёл. От корки до корки, но т.к. не нашёл там ответов на свои вопросы, то и пришёл задавать их здесь. |
| Автор: boostcoder 22.12.2011, 14:13 |
она создает внутреннюю реализацию для указанного типа IP. вообще, никогда не использовал ее) в моих, тоже) |
| Автор: mabrarov 22.12.2011, 16:19 | ||
Если нет висящей (pending, активная) операции ввода/вывода/connect на сокете, то о том, что соединение закрыто узнать трудно. Сомневаюсь, что is_open сообщит о том, что "remote peer is disconnected". Даже если на сокете есть активная операция, то о том, что кто-то порвал/выдернул сетевой шнур TCP/IP-стек сообщит не сразу (если вообще сообщит) - обычно используется application level ping/pong. Многие вопросы отпадут, если почитать http://www.proklondike.com/books/codingproch/codingproch_snader_effective_tcp_ip.html. Удачи. |
| Автор: borisbn 22.12.2011, 16:45 | ||
mabrarov, спасибо, учту.
Уже начал читать. Спасибо. |
| Автор: borisbn 23.12.2011, 09:21 | ||||
| Ну... Чтобы не плодить тем спрошу ещё разок тут. Правильно ли я понимаю, что
означает, что результат чтения/записи/коннекта мне прийдёт в потоке, который вызвал io_service::run() ? Если да, то каким образом мне передать управление (и данные) из этого потока в основной (для отображения графики, например) ? Курить boost::signal ? М.б. strand::wrap() ?
Спасибо. |
| Автор: boostcoder 23.12.2011, 10:32 | ||||||
да.
зависит от фреймворка, который использовался для создания гуя. для куте - http://developer.qt.nokia.com/doc/qt-4.8/qmetaobject.html#invokeMethod. Добавлено через 5 минут и 50 секунд хм... хотя..глядя на код, понимаю что ты другое спрашиваешь. один из способов:
|
| Автор: borisbn 23.12.2011, 11:03 |
| boostcoder, дело в том, что я пишу не программу, а библиотечку, и в каком она будет использована фреймворке мне не нужно знать (чисто для кути я уже сделал такую библиотечку, и "переношу" управление и данные между потоками сигнал/слотами). В частности, мне нужно, чтобы данная библиотека работала из-под дебилдера. Мой класс (строки (1) и (2) из моего псевдокода) будет создаваться в основном потоке билдера, туда же мне и нужно вернуть управление и данные. |
| Автор: boostcoder 23.12.2011, 11:15 | ||
тогда основной поток должен лочится. мне не известны принципы/способы создания программ с использованием билдера. Добавлено через 2 минуты и 9 секунд покажи желаемый пример использования твоей библиотеки. |
| Автор: mabrarov 23.12.2011, 12:32 | ||||
Да нет же! Если серьезно, то (IMHO) красивое решение для Qt я привел в asio samples - qt_echo_server. Достаточно обычной связки Qt signal + Qt slot + http://developer.qt.nokia.com/doc/qt-4.8/qt.html. Добавлено @ 12:37
Делать надо так же как и в Delphi (в Qt это скрывается за Qt::QueuedConnection):
boost::signal с передачей вызова в другой поток (что, по сути, "правильно" можно сделать только при помощи очереди) никак не поможет. Основной поток C++ Builder/Delphi крутит стандартный виндовый message loop. Так что практически единственное решение - кинуть сообщение в него. Ну а в сообщении как-то указать на сам вызов (что и с какими данными). При этом где-то внутрях Delphi можно было повеcить обработчик на Windows message (возможно, на объект класса Application - это лучше, чем на форму). P.S. Что за C++-программисты пошли, что не знают столь древний и почти стандартный трюк... |
| Автор: boostcoder 23.12.2011, 13:35 | ||
возможно потому, что некоторые никогда не видели дельфи, и никогда не использовали winapi. |
| Автор: borisbn 23.12.2011, 13:50 | ||||
Обижаешь, начальник Вот мой код 2006 года (лишнее опускаю)
просто показалось некошерно использовать WinAPI в кроссплатформенном бустовском коде. Думал, что этот трюк можно сделать средствами буста (передача управления и данных из одного потока в другой - читай SendMessage) |
| Автор: mabrarov 23.12.2011, 14:07 | ||
Ну, если подумать за boost-оводов - в каждой ОС своя очередь для основного потока, в консольных приложениях ее вообще нет -> сделать вызов в контексте основного потока без учета всех типов приложений на всех поддерживаемых ОС нереально. Хотя вот в Qt получилось. Ну так у них даже WinMain под виндой свой, да в каждом QThread может быть свой message loop. Не по-boost-вски навязывать столько всего. Юзаешь GUI-вую библиотеку - юзай ее правила/методы вызова в контексте GUI-вого потока. |
| Автор: borisbn 23.12.2011, 16:45 | ||||
Подозревал это, но точно не знал. Жаль. Я ж говорю
Ладно... А то мы уже воду ступе толчём. Спасибо ещё раз. Тему пока не закрываю. М.б. ещё появятся вопросы по asio - буду здесь же задавать, чтоб не плодить однородных тем. |
| Автор: mabrarov 23.12.2011, 17:28 | ||
В том то и дело, что, похоже, дизайн Вашей библиотеки страдает:
|