套接字选择始终返回零

时间:2013-10-16 03:37:22

标签: ios sockets select

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

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;

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()(如果是)。