LINUX.ORG.RU

Ожидание чтения из сокета


0

0

Кусок кода:

while((retn >= MAX_CHUNK)&&(retval>0))
{
retval=0;
retval = select(fd+1,&rdfs,NULL,NULL,&tv);

retn = recv(fd, buf, MAX_CHUNK, NULL);
/*receiving chunks*/

if(retval<=0)printf("No data has arrived in 2 secs\n");

write(fame_d,buf,retn); /*writing chunks into file*/
}

дело в том, что будет retval неположительным или нет - а цикл не закончится, пока не произойдет recv. Как сделать так, чтобы прервать while когда retval вернет что-нибудь <=0 (то есть установленное время для чтения истечет)? То есть, чтоб select служил своего рода таймером?

Плиз, кто может, посоветуйте. Есть ли другой способ поставить таймер на чтение из сокета (чтоб по истечении установленного времени чтение прерывалось, если получено 0 байт)?
Н-дя... наверное, вопрос тупой.

anonymous

типа man select там все есть

anonymous
()

Странно у вас написано:

> retval = select(fd+1,&rdfs,NULL,NULL,&tv);
> retn = recv(fd, buf, MAX_CHUNK, NULL);
> if(retval<=0)printf("No data has arrived in 2 secs\n"); 

Вы пытаетесь читать, не проверив retval. Надо наоборот.

PS: rdfs и tv, по хорошему, надо реинициализировать в цикле, перед
вызовом select.

vnp
()
Ответ на: комментарий от vnp

select должен реагировать на чтение из сокета (изменение дескриптора fd в данном случае). То есть, если из fd что-то получено, retval меняется в 1. Как же можно его ставить после recv? А если recv будет 20 минут ждать куска инфы?

anonymous
()
Ответ на: комментарий от anonymous

>>> retval = select(fd+1,&rdfs,NULL,NULL,&tv);
>>> retn = recv(fd, buf, MAX_CHUNK, NULL);
>>> if(retval<=0)printf("No data has arrived in 2 secs\n"); 

>> Вы пытаетесь читать, не проверив retval. Надо наоборот.

> Как же можно его ставить после recv?

Виноват, плохо выразился. Под "наоборот" имелось в виду "сначала
проверить, а потом читать":

if(retval > 0)
    recv(...);

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

vnp
()
Ответ на: комментарий от vnp

Оказывается, это совсем не выход: данный таймер действует только при первом заходе в цикл.

while((retn >= MAX_CHUNK)&&(retval>0)) { FD_ZERO(&rdfs); FD_SET(fd,&rdfs); tv.tv_sec = 10; tv.tv_usec = 0;

retval=0; retval = select(fd+1,&rdfs,NULL,NULL,&tv); if(retval>0) { retn = recv(fd, buf, MAX_CHUNK, MSG_WAITALL); /*receiving chunks*/ //printf("%s, %d\n", buf, retn); write(fame_d,buf,retn); /*writing chunks into file*/ } else { printf("coudn't get data during 10 seconds"); } }

В остальном, ожидание длится до бесконечности :( Так что select в этой ситуации вряд ли подходит...

Поэтому вопрос хочу повторить: как поставить таймер на чтение из сокета?(желательно, чтоб это не был форканный процесс...)

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.