select立刻返回0,errno=0,根本没有等到超时的情况,为何
...
tv.tv_sec = timeout;
for( ;; )
{
FD_ZERO( &readmask );
FD_SET( sockfd, &readmask );
switch( select( sockfd + 1, &readmask, NULL, NULL, &tv ) )
{
case 0:
return TIMEOUT;
case -1:
if ( errno == EINTR )
continue;
return BROKEN;
default:
if ( FD_ISSET( sockfd, &readmask ) )
{
...
}
}
}
...
奇怪的是,明明timeout> 0,但是select立刻返回0,实际上客户端发送报文是成功的,而服务端却收不到数据(TIMEOUT)。
sockfd是子进程通过recvmsg从父进程接收过来的,父进程那边accept后就用sendmsg发给子进程了,中间没有做其他操作。
本来程序一直正常的,但是最近偶然就会出现这种情况,而且有时几个子进程,有的正常,有的就有这种情况。
各位高手能否指点一下,为什么会出现这种情况?
------解决方案--------------------tv.tv_sec = timeout;
这条语句要在select之前,循环之内。
------解决方案--------------------tv.tv_sec = timeout;
这条语句要在select之前,循环之内。
——————————————————————————
这句话没有必要吧,只读的
——————————————————————————
struct timeval
{
time_t tv_sec;
time_t tv_usec;
};
是不是搂主设的是tv_usec太小了阿,有的系统达不到你设的这个精度就会出现你说的问题
------解决方案--------------------tv.tv_sec = timeout;
这条语句要在select之前,循环之内。
——————————————————————————
这句话没有必要吧,只读的
——————————————————————————
struct timeval
{
time_t tv_sec;
time_t tv_usec;
};
是不是搂主设的是tv_usec太小了阿,有的系统达不到你设的这个精度就会出现你说的问题
-----------
rexp(沧浪客) 说得很好!
man select
...
....
BUGS
Version 2 of the Single UNIX Specification (``SUSv2 ' ') allows systems to
modify the original timeout in place. Thus, it is unwise to assume that
the timeout value will be unmodified by the select() system call.
------解决方案--------------------tv.tv_sec = timeout;
这条语句要在select之前,循环之内。
——————————————————————————
这句话没有必要吧,只读的
——————————————————————————
完全要这样做,因为tv 会被改写成 rest 时间,大部分情况是 0
------解决方案--------------------每次select 之前,设置tv.tv_sec这个时间,应该就可以了。
------解决方案--------------------tv.tv_sec = 5
tv.tv_usec = 0;//add
try it again