Добрый день!
Столкнулся с такой вот проблемой при работе с poll на некоторых устройствах, какой бы таймаут не задавал - первый poll может не дать никакого результата - возвращает 0, а во второй попытке уже есть нужное событие POLLIN. Это случается не всегда, но довольно часто. Это точно не таймаут, тк я пробовал задавать таймаут 30-60 сек., и ситуация так же воспроизводилась, как и на таймауте в 500мс.
Кто ни будь сталкивался с таким поведением?
ps Да, порт конечно же открыт как O_NONBLOCK
...
struct pollfd pfd = { .fd = fd, .events = POLLIN };
...
int retries = 0;
while (retries < 3) {
res = poll (&pfd, 1, ms_to);
if (res <= 0 || pfd.revents != POLLIN) {
retries++;
continue;
}
ssize_t chunksize = read (fd, buf + bytesread, size);
...
Обновление: Теперь работа с tcp запросами на сервер, посылку организовал +/- так же, система debian 10 (если это важно); Стоит таймаут 1000мс ожидания ответа от сервера, примерно на 15 запросов 3-4 остаются без ответа, первое что сделал - увеличил таймаут до 2000мс, да, стало меньше запросов без ответа, но все равно случаются… поставил 5 секунд - ответ от сервера стал приходить стабильно но блин - 5 секунд камон! И тут я вспомнил эту тему.
Как выглядело получение пакета изначально:
ssize_t
recv_to (int fd, void *buf, size_t size, int flags, int ms_to) {
struct pollfd pfd = { .fd = fd, .events = POLLIN };
size_t bytesread = 0;
int res;
while ((res = poll (&pfd, 1, ms_to)) > 0) {
if (pfd.revents != POLLIN) break;
ssize_t chunksize = recv (fd, buf + bytesread, size, flags);
if (chunksize < 0) return chunksize;
if (chunksize == 0) break;
bytesread += chunksize;
size -= chunksize;
if (size == 0) break;
pfd.revents = 0;
}
if (res < 0) return res;
return bytesread;
}
Поделим таймаут на некоторое значение (на 3 например) и будем 3 раза пытаться вызывать poll с укороченным таймаутом. Таймаут ожидания ответа от сервера вернул в 1000мс, вот что получилось:
ssize_t
recv_to (int fd, void *buf, size_t size, int flags, int ms_to) {
struct pollfd pfd = { .fd = fd, .events = POLLIN };
size_t bytesread = 0;
int res;
const int trypoll = 3;
ms_to = ms_to / trypoll;
for (int i = 0; i < trypoll; i++) {
while ((res = poll (&pfd, 1, ms_to)) > 0) {
if (pfd.revents != POLLIN) break;
ssize_t chunksize = recv (fd, buf + bytesread, size, flags);
if (chunksize < 0) return chunksize;
if (chunksize == 0) break;
bytesread += chunksize;
size -= chunksize;
if (size == 0) break;
pfd.revents = 0;
}
if (size == 0) break;
dbgmsg_func ("try tcp poll #%d\n", i + 1);
}
if (res < 0) return res;
return bytesread;
}
На trypoll==2 еще были недополученные пакеты, на trypoll==3 уже нет… WTF? Мне кажется, что я что-то делаю не так, как-то не правильно работаю с poll, но у меня нет никаких идей, почему 3 poll c таймаутом 333мс работают а один с таймаутом 1000мс - нет.
Что думаете?