0

我创建了一个套接字来接收服务器数据,并采用非阻塞模式,但我很困惑为什么选择总是返回零?这会使我的播放器播放或暂停片刻,如果您需要任何进一步的信息,请告诉我。

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;
4

1 回答 1

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()它。

于 2013-10-16T04:04:08.983 回答