Применение тайм-аута к UDP-вызову receive_from в ASIO

У меня есть следующий бит кода ASIO, который синхронно читает пакеты UDP. Проблема в том, что если в данный промежуток времени (30 секунд) не поступили пакеты данных заданного размера, я бы хотел, чтобы функция recieve_from возвращала с какой-то ошибкой, чтобы указать время ожидания.

for (;;)
{
boost::array<char, 1000> recv_buf;
udp::endpoint remote_endpoint;
asio::error_code error;

socket.receive_from(asio::buffer(recv_buf),   // <-- require timeout
remote_endpoint, 0, error);

if (error && error != asio::error::message_size)
throw asio::system_error(error);

std::string message = make_daytime_string();

asio::error_code ignored_error;
socket.send_to(asio::buffer(message),
remote_endpoint, 0, ignored_error);
}

Если посмотреть на документацию, то не для вызовов, ориентированных на UDP, поддерживается механизм тайм-аута.

Как правильно (также, если возможно, переносимо) использовать тайм-аут с синхронными вызовами UDP в ASIO?

1

Решение

Насколько я знаю, это невозможно. Запустив синхронный receive_from вы заблокировали выполнение кода системным вызовом recvmsg от #include <sys/socket.h>,

Что касается переносимости, я не могу говорить за Windows, но решение на основе Linux с BSD будет выглядеть так:

void SignalHandler(int signal) {
// do what you need to do, possibly informing about timeout and calling exit()
}

...
struct sigaction signal_action;
signal_action.sa_flags = 0;
sigemptyset(&signal_action.sa_mask);
signal_action.sa_handler = SignalHandler;
if (sigaction(SIGALRM, &signal_action, NULL) == -1) {
// handle error
}
...
int timeout_in_seconds = 5;
alarm(timeout_in_seconds);
...
socket.receive_from(asio::buffer(recv_buf), remote_endpoint, 0, error);
...
alarm(0);

Если это вообще невозможно, я бы порекомендовал перейти на полную асинхронность и запустить ее в boost::asio::io_service,

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector