web-dev-qa-db-fra.com

UDP Socket Set Timeout

J'essaie de définir un délai d'expiration de 100 ms sur un socket UDP. J'utilise C. J'ai posté des morceaux pertinents de mon code ci-dessous. Je ne sais pas pourquoi ce n'est pas une fin de temps mais un blocage quand il ne reçoit pas de segment. Cela ne fonctionne-t-il que sur les sockets qui ne sont pas liés à l'aide de la méthode bind ()?

#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++;
}
25
rharrison33

L'option SO_RCVTIMEO attend un struct timeval défini dans sys/time.h, et non un entier comme celui que vous lui transmettez. Le timeval struct a comme champ pour les secondes et un champ pour les microsecondes. Pour définir le délai d’expiration sur 100 ms, procédez comme suit:

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

J'ai le même problème. J'ai essayé d'adopter la solution que vous avez suggérée, en utilisant la structure timeval. Mais cela n'a pas semblé fonctionner. 

J'ai lu dans la documentation Microsoft et l'heure devrait être une DWORD avec le nombre de millisecondes, mais il y a aussi une autre chose à faire, si le socket est créé à l'aide de la fonction WSASocket, le paramètre dwFlags doit avoir l'attribut WSA_FLAG_OVERLAPPED défini le délai d'attente pour fonctionner correctement . Sinon, le délai d'attente ne prend jamais effet.

0
user9510357