2012-11-25 8 views
22

Ich versuche, ein 100ms Timeout auf einem UDP-Socket zu setzen. Ich benutze C. Ich habe relevante Teile meines Codes unten veröffentlicht. Ich bin mir nicht sicher, warum das kein Zeitlimit ist, sondern hängt nur, wenn es kein Segment erhält. Funktioniert das nur für Sockets, die nicht mit der Methode bind() gebunden sind?UDP Socket Set Timeout

#define TIMEOUT_MS  100  /* Seconds between retransmits */ 

if ((rcv_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) 
    DieWithError("socket() failed"); 

if ((rcv_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) 
    DieWithError("socket() failed"); 

//set timer for recv_socket 
static int timeout = TIMEOUT_MS; 
setsockopt(rcv_sock, SOL_SOCKET, SO_RCVTIMEO,(char*)&timeout,sizeof(timeout)); 

if(recvfrom(rcv_sock, ackBuffer,sizeof(ackBuffer), 0, 
     (struct sockaddr *) &servAddr2, &fromSize) < 0){ 
    //timeout reached 
    printf("Timout reached. Resending segment %d\n", seq_num); 
    num_timeouts++; 
} 
+2

Es sieht so aus, als würden Sie den Rückgabewert von 'setsockopt' nicht überprüfen, um zu sehen, ob es einen Fehler zurückgegeben hat. Es ist wahrscheinlich. 'SO_RCVTIMEO' ist sowohl auf Linux als auch auf MacOS dokumentiert, um ein' struct timeval' zu nehmen, aber Sie übergeben ein 'int'. Übergeben Sie stattdessen ein 'struct timeval'. Warum werfen Sie '& timeout' auch auf' char * '? Es ist überhaupt kein 'Char *'. – Celada

Antwort

40

Die SO_RCVTIMEO Option erwartet eine struct timeval definiert in sys/time.h, nicht eine ganze Zahl wie Sie es vorbei sind. Die timeval struct hat als Feld für Sekunden und ein Feld für Mikrosekunden. Um das Zeitlimit auf 100 ms zu setzen, sollte Folgendes der Fall sein:

struct timeval tv; 
tv.tv_sec = 0; 
tv.tv_usec = 100000; 
if (setsockopt(rcv_sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) < 0) { 
    perror("Error"); 
}