Для этого можно использовать функцию select
. Он может проверить, есть ли новый вход в сокете для чтения, и у него есть тайм-аут, поэтому его можно использовать и для вашего таймера.
Он существует в той или иной форме во всех основных операционных системах. Просто выполните поиск Google для socket select <your operating system> example
, и вы получите множество результатов.
Последний аргумент select
используется для тайм-аута. Это указатель на struct timeval
, структуру, которая содержит поля для установки времени ожидания.
Если этот указатель передается как NULL
, то тайм-аут не существует, и select
может блокироваться бесконечно.
Чтобы установить тайм-аут, вам необходимо установить в поле tv_sec
структуры timeval
количество секунд, а в поле tv_usec
- количество микросекунд (должно быть меньше миллиона). Вы можете установить тайм-аут на ноль, т. Е. Просто быстрый опрос, установив эти поля на ноль.
Если select
возвращает ноль, значит, был тайм-аут.
Пример с тайм-аутом 1,5 секунды:
for (;;)
{
fd_set readset;
int maxfd;
/* Initialize and set `readset` and `maxfd` */
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 500000;
int res = select(maxfd + 1, &readset, NULL, NULL, &tv);
if (res == -1)
perror("select"); /* Error */
else if (res == 0)
{
/* Timeout, do something */
}
else
{
/* A socket in `readset` is readable */
}
}
Если select
возвращает до тайм-аута, структура timeval
изменяется так, чтобы содержать оставшееся время тайм-аута.