![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
всем доброго дня.
в asio, синхронные read()/write() продолжаются вечно, пока не будет прочитано/записано требуемое кол-во байт. мне требуется блокирующие чтение/запись с таймаутом. в экзамплах asio есть примеры реализации такого поведения: 1. blocking_tcp_client. 2. blocking_udp_client. но они не подходят потому, что для блокировки вызывающего потока используют метод io_service::run_one(). у такой реализации особенность в том, что для того чтоб она работала, нужен отдельный io_service на каждую такую реализацию. а это не хорошо.. вопрос в том, каким образом реализовать блокирующие чтение/запись, имея один io_service и множество сокетов? при этом, хотелось бы иметь возможность использовать все это дело И с обычными асинхронными чтением/записью. спасибо. Это сообщение отредактировал(а) boostcoder - 29.5.2011, 07:08 |
|||
|
||||
mabrarov |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 100 Регистрация: 12.1.2011 Где: Казань Репутация: 8 Всего: 9 |
Буду краток:
1) SO_RCVTIMEO/SO_SNDTIMEO (совместно с socket::native()) или 2) deadline_timer Но в обоих случаях - ничего кроме как закрыть сокет вы не сможете. Для асинхронных операций на Windows Vista+ вроде бы должен сносно работать метод socket::cancel(), но вот беда - asio при сборке старается угодить всем и работает даже под Vista так как будто работа ведется под Windows XP - т.е. что-то там "мудрит" с cancel и потоками. Я рекомендую никогда не использовать cancel() - только close() одинаково поддерживают все платформы. И вина тут в общем-то не asio, а WinSock или даже Berkley Sockets. Про SO_RCVTIMEO/SO_SNDTIMEO рекомендую почитать MSDN. Гугл говорит, что "MSDN говорит", что состояние сокета после такого таймаута не определено и безопасно он может быть только закрыт. |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
mabrarov, спасибо.
немного расстроился.. :( буду думать... |
|||
|
||||
mabrarov |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 100 Регистрация: 12.1.2011 Где: Казань Репутация: 8 Всего: 9 |
Да что тут расстраиваться.. это же логично - после отмены хз, что там принялось/отправилось, а что нет. А во-вторых IMHO, синхронные операции ввода/вывода (особенно в сети) must die. Многие (C#, Apache MINA, Twisted), только сейчас начинают это понимать. И еще, не забывайте, что если socket-layer сказал вам "я все отправил" - это вовсе не означает, что он что-то там вообще отправил (есть буфер отправки). И уж тем более не означает, что что-то дошло до другого конца. Читайте Йона Снейдера "Эффективное программирование TCP-IP" - вот там все мифы очень четко рассеиваются и логично объясняется работа сокетов без излишних подробностей работы TCP/UDP. |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
не удержался:
![]() |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
![]() |
|||
|
||||
cupper |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 525 Регистрация: 29.11.2006 Репутация: 1 Всего: 1 |
нужно тоже самое. Но у меня есть возможность создавать на каждый сокет свой io_service, но я фигею от логики deadline_timer. И везде где я видел в случае если тайпер истекает закрывается сокет, но зачем ??? я даже боюсь представить что для того что бы операция чтения которая весит где "там" вернула управление. Надеюсь это не так, и после истечения таймера можно на том же сокете вызвать еще раз операцию получения данных ? |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
tzirechnoy |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1173 Регистрация: 30.1.2009 Репутация: 2 Всего: 16 |
Под юниксами я бы посоветовал использовать обёртку над неблокирующим сокетом и единичным poll(). Вполне делается полная имитацыя read/write с таймаутом.
|
|||
|
||||
newbee |
|
|||
![]() Бревно ![]() ![]() Профиль Группа: Участник Сообщений: 703 Регистрация: 24.8.2011 Репутация: 4 Всего: 19 |
Я бы делала с помощью select. Открывала дескриптор, клала его в пул селекта и вызывала select с нужным таймаутом. Но вообще это часть реализации асинхронного взаимодействия, не понимаю, зачем этим пользоваться непосредственно.
Добавлено через 37 секунд Ну да, poll уже посоветовали ![]() -------------------- You're face to face With man who sold the world |
|||
|
||||
cupper |
|
||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 525 Регистрация: 29.11.2006 Репутация: 1 Всего: 1 |
при истечении таймера сокет закрывается. Но зачем ? Ответ вероятно что для того что бы прервать блокирующую операцию чтения. Но это же о плохо.
надо кроссплаптформенно
Хм... я почему то был уверен что сама операция read умеет с timeout работать... Видать напутал. А нужно это вот для чего: есть у меня UDP сокет, я его слушаю, и если за определенный интервал времени не будет получено нужного сообщения то нужно сделать некоторую реакцию. По логике если я не получу нужный мне мессадж, то далее сокет открытым держать нет смысла. Поэтому и deadlite_timer сойдет. |
||||||
|
|||||||
newbee |
|
|||
![]() Бревно ![]() ![]() Профиль Группа: Участник Сообщений: 703 Регистрация: 24.8.2011 Репутация: 4 Всего: 19 |
select как раз относительно кроссплатформенен. POSIX.1-2001 + 4.4BSD + винда.
Странно, что такого функционала не предоставляет используемая тобой библиотека асинхронных сокетов. -------------------- You're face to face With man who sold the world |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
cupper |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 525 Регистрация: 29.11.2006 Репутация: 1 Всего: 1 |
хехе, ну так я и использую asio который это делает через deadline_timer который может прервать операцию чтения только закрыв сокет, что мне изначаьлно и не особо понравилось.
это не требования а вытекающее последствие из задачи. А если мне нужно было по истечению таймера сделать что то, и опять продолжить слушать на том же сокете ? Пересоздавать его ? |
||||
|
|||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
cupper, так ###! есть же cancel().
мне такое решение не подходило, ибо использовался блокирующий ввод-вывод. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |