2017-04-21 27 views
0

我正在使用我的客戶機寫入服務器。我想檢查套接字是否在我的客戶端中寫入,如果在建立連接後它尚未準備好10秒,那麼我想打印一條錯誤消息並由於超時而退出我的客戶端。在使用send()之前用select()檢查套接字

客戶端只使用發送功能就能正常工作,並且能夠將文件從客戶端傳輸到服務器。然而,當我實現的select()功能,客戶現在只是超時與sel_value被設置爲0

爲了便於閱讀,我已刪除了我的代碼,不會發送功能,因爲有一些用於將內容讀入緩衝區的附加邏輯。

//set up select for sending 
fd_set wfds; 
struct timeval timeout; 
while (1) { 
    FD_ZERO(&wfds); 
    FD_SET(sockfd, &wfds); 

    timeout.tv_sec = 10; 
    timeout.tv_usec = 0; //no us 

    int sel_value = select(sockfd+1, &wfds, NULL, NULL, &timeout); 
    cout<<"sel_value is: "<<sel_value<<endl; 
    if(sel_value == -1){ 
     perror("select"); 

    }else if(sel_value == 0){ 
     printf("Timeout. Cannot send for 10s \n"); 
     break; 
    } 
    else{ 
     if(FD_ISSET(sockfd, &wfds)){ 
      //my code never reaches this point, but here is where we send 
      //code to send stuff 
     } 
    } 

} 

回答

0

你正在做這個事情。您只需執行發送,並且只有在發送EAGAIN/EWOULDBLOCK時才選擇可寫。套接字幾乎總是準備好寫入,除非套接字發送緩衝區已滿。你的方式是將系統調用加倍並增加延遲。

+0

我有點困惑。如果我做了發送,那麼我需要檢查errno = EAGAIN || errno = EWOULDBLOCK。如果errno是這些值之一,我是否嘗試重新發送?是通過調用select()然後讀取它的返回值來實現這一點的一種方法:如果它準備好寫入,那麼我可以執行continue(),然後返回到循環中的發送? – jonnyd42

+0

我已經回答了。如果'errno'是EAGAIN/EWOULDBLOCK,則選擇。 – EJP

+0

即使我的套接字被阻塞,你所說的工作是否仍然有效? – jonnyd42

相關問題