2012-11-25 14 views
11

Sto utilizzando socket c per implementare un protocollo UDP affidabile. Sto usando il seguente codice per impostare un timeout su un socket in cui sto aspettando un riconoscimento. Non sono sicuro del motivo per cui sto ricevendo errno 11, risorsa temporaneamente non disponibile.Errno: 11, Risorsa temporaneamente non disponibile

 //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++; 
     } 

Ho anche provato il metodo di selezione indicato nei commenti. Ho il seguente codice all'interno di un ciclo, ma il recvfrom non va mai fuori tempo.

 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

Provare a utilizzare le prese select() e non bloccanti. L'approccio select() è molto più flessibile, affidabile e portatile. –

+0

Non c'è nessuna chiamata a 'recvfrom()' int he second snippet. – alk

+0

'recvfrom()' restituisce 'ssize_t' not' int', BTW. – alk

risposta

13

Quando si chiama recvfrom() su un socket di blocco e un time out era stata impostata con setsockopt() è normale per ottenere l'errore EAGAIN (11) nel caso in cui la chiamata a recvfrom() volte su (vale a dire: nessun dato è stato ricevuto nel tempo periodo specificato come timeout).

Verbatim da man recvfrom:

VALORE DI RITORNO

...

ERRORI

... .

EAGAIN o EWOULDBLOCK La presa è contrassegnata non bloccante e l'operazione di ricezione potrebbe bloccare, o un timeout ricevere era stato impostato e il timeout scaduto prima che i dati sono stati ricevuti. ...

per aggirare il problema: Basta chiamare recvfrom() di nuovo ... ;-)

+1

Risposta stupenda! Grazie! – rharrison33

0

Per me, il problema era dovuto a pacchetti IPv6 in arrivo su un socket UDP legato ad una particolare porta. Questi stavano attivando select() ma quando ho provato a leggerli usando recvfrom() la chiamata ha restituito "Resource temporaneamente non disponibile". Non ho bisogno di IPV6 per la mia applicazione, quindi l'ho semplicemente disabilitato tramite sysctl.conf. Il problema ora è andato via!

Problemi correlati