我创建一个接收服务器数据的套接字,并采用非阻塞模式,但我很困惑为什么选择总是返回零?这让我的播放器播放或暂停片刻, 如果您需要任何进一步的信息,请告诉我。
int ret = 0;
int timeout = 0;
while(http->work_flag)
{
fd_set readSet;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 80*1000;
FD_ZERO( &readSet );
FD_SET( http->fd, &readSet );
ret = select(http->fd + 1,&readSet,0,0,&tv);
printf("%d\r\n",ret);
if ( ret > 0 ) {
ret = recv(http->fd,buf,size,0);
if( ret <= 0 ){
ret = -1;
}
else {
http->total_bytes += ret;
http->continue_pkt++;
}
return ret;
}
else if( ret < 0 ) {
http->continue_pkt = 0;
return -1;
}
else if( ret == 0 ) {
http->continue_pkt = 0;
//time out
timeout++;
if( timeout > 12*30 ) //30seconds
return -1;//timeout
}
}
return -1;
答案 0 :(得分:0)
如果您完全摆脱循环并让select()
为您管理超时,您是否遇到同样的问题?
fd_set readSet;
struct timeval tv;
tv.tv_sec = 30;
tv.tv_usec = 0;
FD_ZERO( &readSet );
FD_SET( http->fd, &readSet );
int ret = select(http->fd + 1, &readSet, 0, 0, &tv);
printf("%d\r\n", ret);
if( ret <= 0 )
{
// error or timeout
http->continue_pkt = 0;
return -1;
}
ret = recv(http->fd, buf, size, 0);
if( ret <= 0 )
{
// error or disconnect
return -1;
}
http->total_bytes += ret;
http->continue_pkt++;
return ret;
在具有较小超时的循环中调用select()
的唯一原因是,如果您尝试使读取逻辑尽快中止。为此,您可以通过pipe()
创建一个单独的管道,并将其与套接字放在同一个fd_set
中,然后在管道中写入内容,以便在需要时“唤醒”select()
。当select()
返回> 0
时,代码可以检查管道是否已发出信号并退出而不调用recv()
(如果是)。