Вопрос программистам под UNIX

Dimic-rok

В функции выполняется следующий код:
FD_ZERO(&readFds);
FD_SET(s, &readFds);
int stat=select(FD_SETSIZE, &readFds, NULL, NULL, &time);
if (stat < 0) {
printf("class icmp_sock: select error\n");
};
if (stat == 0) return 0;

stat=read(s,p->data,IP_MAXPACKET);
Все работает замечательно, если в s есть данные мы их читаем, если нет, то выходим. Вопрос: почему если не использовать select а сразу считывать, а в s нет данных, то пограмма подвисает на read? по идее read в этом случае должна вернуть 0. И второй вопрос: как кроме select можно узнать есть ли данные в s или нет (select мне не подходит своим таймаутом - минимальное время вызова select в Free BSD если в s не появились данные 10 мс)

abrek

if (stat < 0) {
printf("class icmp_sock: select error\n");
};
А где же return после ошибки?
И ещё на errno==EINTR неплохо бы проверить.
> почему если не использовать select а сразу считывать, а в s нет данных, то пограмма подвисает на read?
потому что O_NONBLOCK не поставил с помощью fcntl(2)
> И второй вопрос: как кроме select можно узнать есть ли данные в s или нет (select мне не подходит своим таймаутом - минимальное время вызова select в Free BSD если в s не появились
> данные 10 мс)
poll(2) с нулевым таймаутом
а то и сразу read(2 если ситуация позволяет

bobking

Если FreeBSD, то kevent.

Dimic-rok

Спасибо, вроде разобрался.

TYU_2008

struct kevent kv;
а в kv.data в случае сокета будет сколько там приехало. мелочь, а приятно - не надо делать лишних read'ов. вообще, kqueue рулит

Dimic-rok

А как можно очистить сокет от всех пакетов в нем, не считывая их из него?

abrek

Судя по твоим вопросам, ты что-то не то делаешь
Зачем чистить буфер от пакетов?
Наверное, проще всего переоткрыть сокет.

sergey_m

Отчего такое желание возникает? Не могу представить ситуации когда такое нужно делать.

Dimic-rok

Есть такая ситуация

sergey_m

Может быть есть какое-то другое решение? Расскажи ситуацию если не секрет.

Dimic-rok

Программа аналогичная пингу. В сеть посылаются пакеты, когда сеанс измерения закончен в сокете еще будет находиться энное количество пакетов. После необходимо его очистить и провести новый сеанс.

abrek

Всё-таки ты что-то не так делаешь. А что именно, по такому короткому описанию не понять.

Dimic-rok

Ну что же не понятно? Измерения окончены, а пакеты из сети продолжают еще приходить (но они мне уже не нужны). Так вот их и нужно удалить из сокета перед следующим сеансом.

sergey_m

Реально закрыть и открыть новый для следующего сеанса будет лучше.

abrek

Уважай труд тех, кто доставляет пакеты - читай их из буфера!
Проблема мне кажется не принципиальной - может ведь прийти и после начала следующего сеанса, тогда всё равно читать придётся, и отделять от "правильных" пакетов. А может ещё просто "шум" какой-нибудь свалиться, в этом ихнем интернете всякое бывает.
Оставить комментарий
Имя или ник:
Комментарий: