2013-10-16 43 views
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; 
+0

可能对您有帮助https://discussions.apple.com/message/7815634?messageID=7815634#7815634?messageID=7815634 – Sport

+0

如果'ret'为零,您应该返回零,以便呼叫者知道关闭FD。目前,您正在将流结束与错误情况混为一谈。 – EJP

回答

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

+0

它也会发生,但如果我摆脱超时,并设置tv.tv_usec = 800 * 1000;它可以很好地工作。 – Junhg

+0

但如果ret <0,那将会重新连接。 – Junhg