2012-11-25 73 views
11

我使用c套接字來實現可靠的UDP協議。我正在使用下面的代碼來設置一個套接字上的等待確認的超時。我不知道爲什麼我得到errno 11,資源暫時不可用。Errno:11,資源暫時不可用

 //set timer for recv_socket 
     struct timeval tv; 
     tv.tv_usec = TIMEOUT_MS; 

     if(setsockopt(rcv_sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) < 0){ 
      printf("Error setting the socket timeout.\n"); 
     } 

     int recv_msg_len; 
     if(recv_msg_len = recvfrom(rcv_sock, ackBuffer,sizeof(ackBuffer), 0, 
       (struct sockaddr *) &servAddr2, &fromSize) < 0){ 
      //timeout reached 
      printf("Error Reporting: %d : %s\n", errno, strerror(errno)); 
      num_timeouts++; 
     } 

我也嘗試過在評論中提到的select方法。我在循環內有下面的代碼,但recvfrom永遠不會超時。

 fd_set set; 
     FD_ZERO(&set);  /* empties the set */ 
     FD_CLR(rcv_sock,&set); /* removes FD from the set */ 
     FD_SET(rcv_sock,&set); /* adds FD to the set */ 

     if(select(rcv_sock + 1, &set, NULL, NULL, &tv) < 0){ 
      printf("\nError Reporting: %d : %s\n\n", errno, strerror(errno)); 
      return -1; 
     } 


     if(!FD_ISSET(rcv_sock,&set)){ /* true if FD is in the set */ 
      printf("socket is not set properly.\n"); 
     } 
+0

請嘗試使用select()和非阻塞套接字。 select()方法更加靈活,可靠和便攜。 –

+0

沒有調用'recvfrom()'int他的第二個片段。 – alk

+0

'recvfrom()'返回'ssize_t'而不是'int',順便說一句。 – alk

回答

13

當調用recvfrom()阻塞插座上了一直在使用setsockopt()這屬於正常誤差EAGAIN (11)的情況下調用recvfrom()超時(即設置一個時間:沒有數據的時間收到期限規定爲超時)。

逐字從man recvfrom

返回值

...

錯誤

... 。

EAGAIN或EWOULDBLOCK 插座被標記非阻塞和接收操作會阻塞,或接收超時已被設定和被接收之前數據 超時。 ...

要解決這個問題:再打電話recvfrom() ...... ;-)

+1

太棒了!謝謝! – rharrison33

0

對於我來說,這個問題是由於到達上綁定到特定端口的UDP套接字IPv6數據包。這些觸發了select(),但是當我嘗試使用recvfrom()讀取它們時,調用返回「資源暫時不可用」。我的應用程序不需要IPV6,所以我只是通過sysctl.conf將其禁用。問題現在消失了!

相關問題