Изучаю boost::asio.
Пример (все async операции для одного io_service.run):
void timerHandler(const boost::system::error_code& error)
{
if (!error)
{
//запись в socket
}
}
void readHandler(const boost::system::error_code& e, std::size_t bytes_transferred)
{
if (!e)
{
//прочитали данные размером длины буфера, выполняем к примеру запись ответа
}
}
//ожидаем таймер
timer.async_wait(timerHandler);
...
boost::asio::async_read(socket, boost::asio::buffer(buffer), readHandler); // читаем пока буфер не заполниться
Необходимо при отсутствии данных в течение некоторого времени записать в socket тестовую посылку. Может быть следующая последовательность событий:
1) прочитали часть посылки
2) сработал таймер ???
Каким образом можно избежать данной последовательности?
Данная последовательность не должна появляться, потому как после чтения чего-либо из socket, таймер должен остановиться и после получения всей посылки запуститься.
Думаю что надо использовать вариант async_read для чтения с условием, а в обработчике проверки условия после первого байта останавливать таймер, а после последнего запускать
19.05.09 08:06: Перенесено из 'Средства разработки'
Здравствуйте, kvser, Вы писали:
K>Необходимо при отсутствии данных в течение некоторого времени записать в socket тестовую посылку. Может быть следующая последовательность событий: K>1) прочитали часть посылки K>2) сработал таймер ??? K>Каким образом можно избежать данной последовательности? K>Данная последовательность не должна появляться, потому как после чтения чего-либо из socket, таймер должен остановиться и после получения всей посылки запуститься.
Не совсем понятно что означает "посылка". Это какая-то структура переменной длины или фиксированный массив байт?
async_read вызовет хендлер только при полном заполнении буффера или при ошибке. Если посылка целиком умещается в буфер, то такая ситуация невозможна, при условии что io_service::run() запущен в одном потоке.
K>Думаю что надо использовать вариант async_read для чтения с условием, а в обработчике проверки условия после первого байта останавливать таймер, а после последнего запускать
Получите первый байт, остановите таймер, после этого произойдет задержка и следующий байт получите только через 10 часов, а таймер то выключен
Здравствуйте, Vinick, Вы писали:
K>>Необходимо при отсутствии данных в течение некоторого времени записать в socket тестовую посылку. Может быть следующая последовательность событий: K>>1) прочитали часть посылки K>>2) сработал таймер ???
V>Не совсем понятно что означает "посылка". Это какая-то структура переменной длины или фиксированный массив байт?
псылка/сообщение/и т.д. в данном контексте означает последовательность байт фиксированной длины, которая читается в буфер соответствующего размера
V>async_read вызовет хендлер только при полном заполнении буффера или при ошибке. Если посылка целиком умещается в буфер, то такая ситуация невозможна, при условии что io_service::run() запущен в одном потоке.
Вы хотите сказать что, если началось чтение, то хандлер таймера не вызовется пока не заполниться весь буфер? но это же не так
K>>Думаю что надо использовать вариант async_read для чтения с условием, а в обработчике проверки условия после первого байта останавливать таймер, а после последнего запускать V>Получите первый байт, остановите таймер, после этого произойдет задержка и следующий байт получите только через 10 часов, а таймер то выключен
неее, за это отвечает другой таймер, назовем его t2
а про таймер который я говорю(назовем его t3), работает для того чтобы, если не было никаких сообщений некоторое время, то послать сообщение проверки связи
Здравствуйте, kvser, Вы писали:
K>Здравствуйте, Vinick, Вы писали:
K>>>Необходимо при отсутствии данных в течение некоторого времени записать в socket тестовую посылку. Может быть следующая последовательность событий: K>>>1) прочитали часть посылки K>>>2) сработал таймер ???
K>Вы хотите сказать что, если началось чтение, то хандлер таймера не вызовется пока не заполниться весь буфер? но это же не так
Я хочу сказать что при использовании async_read и при условии что размер буфера точно равен размеру сообщения, нет понятий "началось чтение" и "принята часть сообщения". В этом случае для приложения чтение происходит мгновенно в момент вызова readHandler,все остальное скрыто в библиотеке.
Если таймер сбрасывать и снова взводить в readHandler, то можно отследить таймаут между приемом двух сообщений.
Если async_read заменить async_read_some (в этом случае придется самостоятельно буферизовать и разделять сообщения),и перед вызовом async_wait устанавливать какой-нибудь флаг, в readHandler этот флаг сбрасывать, а в timerHandler проверять состояние флага, то можно детектировать отсутствие данных на сокете в течении определенного времени.
K>неее, за это отвечает другой таймер, назовем его t2 K>а про таймер который я говорю(назовем его t3), работает для того чтобы, если не было никаких сообщений некоторое время, то послать сообщение проверки связи
А так ли нужны такие сложности. Может достаточно проверять просто отсутствие данных на сокете в течении определенного времени, безотносительно целое сообщение или его часть.
Здравствуйте, Vinick, Вы писали:
V>Я хочу сказать что при использовании async_read и при условии что размер буфера точно равен размеру сообщения, нет понятий "началось чтение" и "принята часть сообщения". В этом случае для приложения чтение происходит мгновенно в момент вызова readHandler,все остальное скрыто в библиотеке.
вот меня и волновало как там в библиотеке, если я читаю 6 байт, а после чтения 4 сработает таймер, по которому данные записываются в сокет, то как поведет библиотека себя. Не надо ли предпринимать каких-либо дополнительных действий. получается что не надо
V>Если таймер сбрасывать и снова взводить в readHandler, то можно отследить таймаут между приемом двух сообщений.
K>>неее, за это отвечает другой таймер, назовем его t2 K>>а про таймер который я говорю(назовем его t3), работает для того чтобы, если не было никаких сообщений некоторое время, то послать сообщение проверки связи V>А так ли нужны такие сложности. Может достаточно проверять просто отсутствие данных на сокете в течении определенного времени, безотносительно целое сообщение или его часть.
Здравствуйте, Vinick, Вы писали:
K>А так ли нужны такие сложности. Может достаточно проверять просто отсутствие данных на сокете в течении определенного времени, безотносительно целое сообщение или его часть.
и был вопрос в том, что произойдет если только часть сообщения успеет обработаться async_read'ом. Подумывал о том, чтобы после получения хотя бы байта, перезапускать таймер t3, потому что если он сработает во время выполнения async_read, то надо писать в сокет и ждать ответа уже на это тестовое сообщение. Получается что при следующем чтении, ожидая ответ на тестовое сообщение, я начну получать из какого-то "библиотечного" буфера остаточные данные недополученного ранее сообщения, в результате неправильный ответ на тест и дисконнект.
А за время чтения отвечает другой таймер t2