2013-10-16 91 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