2012-11-25 13 views
22

Próbuję ustawić limit czasu 100ms na gnieździe UDP. Używam C. Opublikowaliśmy relavent kawałki mojego kodu poniżej. Nie wiem, dlaczego nie upłynął limit czasu, ale po prostu zawiesza się, gdy nie otrzymuje segmentu. Czy działa to tylko na gniazdach, które nie są związane za pomocą metody bind()?Limit czasu UDP dla gniazda UDP

#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

Wygląda na to, że nie sprawdzasz wartości zwracanej przez 'setsockopt', aby sprawdzić, czy zwrócił błąd. Prawdopodobnie tak jest. 'SO_RCVTIMEO' jest udokumentowane zarówno w systemach Linux, jak i MacOS, aby uzyskać' struct timeval', ale przekazujesz 'int'. Spróbuj podać 'struct timeval' zamiast tego. Ponadto, dlaczego przesyłasz '& timeout' do' char * '? To wcale nie jest "char *". – Celada

Odpowiedz

40

Opcja SO_RCVTIMEO oczekuje struct timeval zdefiniowane w sys/time.h, a nie całkowitą jakbyś przechodząc do niego. timeval struct ma pole dla sekund i pole dla mikrosekund. Aby ustawić limit czasu na 100ms, należy wykonać następujące czynności:

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"); 
}