2012-11-25 6 views
11

Ich verwende C-Sockets, um ein zuverlässiges UDP-Protokoll zu implementieren. Ich verwende den folgenden Code, um ein Timeout für einen Socket festzulegen, in dem ich auf eine Bestätigung warte. Ich bin nicht sicher, warum ich errno 11 bekomme, Ressource vorübergehend nicht verfügbar.Errno: 11, Ressource vorübergehend nicht verfügbar

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

Ich habe auch die select-Methode versucht, die in den Kommentaren erwähnt wurde. Ich habe den folgenden Code innerhalb einer Schleife, aber die recvfrom nie aus.

 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

Verwenden Sie stattdessen die Select() - und nicht blockierenden Sockets. Der select() -Ansatz ist viel flexibler, zuverlässiger und portabler. –

+0

Im zweiten Snippet wird 'recvfrom()' nicht aufgerufen. – alk

+0

'recvfrom()' gibt 'ssize_t' nicht' int' zurück, BTW. – alk

Antwort

13

Wenn recvfrom() auf einem blockierenden Socket aufrufen und eine Auszeit eingestellt worden war setsockopt() mit es ist normal, um den Anruf zu recvfrom() mal aus den Fehler EAGAIN (11) zu erhalten, falls (das heißt: keine Daten wurden in der Zeit empfangen Zeitraum als Zeitlimit angegeben).

Verbatim von man recvfrom:

UCKGABEWERT

...

Fehler

... .

EAGAIN oder EWOULDBLOCK Die Buchse ist nonblocking markiert und der Vorgang erhalten würde blockieren, oder ein Timeout empfangen hatte eingestellt und die Timeout abgelaufen, bevor Daten empfangen wurde. ...

Um dies zu umgehen: Just recvfrom() wieder anrufen ... ;-)

+1

Super Antwort! Vielen Dank! – rharrison33

0

Für mich war das Problem zu IPv6-Paketen durch einen UDP-Socket an einem bestimmt Port gebunden ankommen. Diese lösten das select() aus, aber als ich versuchte, sie mit recvfrom() zu lesen, gab der Aufruf "Ressource vorübergehend nicht verfügbar" zurück. Ich brauche IPV6 nicht für meine Anwendung, also habe ich es einfach über sysctl.conf deaktiviert. Problem jetzt weg!

Verwandte Themen