简体   繁体   中英

Setting a timeout on a socket is not working

I'm using the setsockopt() function to set a timeout on the recvfrom() function. Because of the protocol I am using, I have to first have a timeout of 2 secs, then 4, 6, until a max. But when I use the function, it seems to have a 0.01 seconds timeout because it sends 8 packets without waiting.

//more variables and code here
struct timeval timeout = {2,0};

while(1){
  setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(struct timeval));
  temp2 = recvfrom(sock, &buff, sizeof(buff), 0, (struct sockaddr *)&addr_server, sizeof(addr_server));

  if(temp2 < 0){ /* Timeout excedit (exceeded)*/
      temp = sendto(sock, (struct udp_PDU*)&reg_pdu, sizeof(reg_pdu), 0, (struct sockaddr *)&addr_server, sizeof(addr_server));
      if(temp == -1){
        printf("Error sendTo \n");
        exit(-1);
      }
      packet_counter++;
      debug("Enviat paquet REGISTER_REQ");
      if(packet_counter == 8) break;
      if((interval * max) > t ) timeout.tv_sec+=interval;

  }else{ /* s'han rebut dades (they have rebooted) */
    correct = 1;
    break;
  }
}

A timeout (Such as what you are implementing.) is not a delay statement. Rather it is a method to prevent a call such as recv() , or recvfrom() from blocking indefinitely. If data traffic shows up earlier than the timeout is set for, all the better. The function receives it, and program flow continues. The timeout, as you have it, waits up to 2 seconds for something to happen. If nothing happens, then it allows the method to stop waiting, and for your program execution to continue, ie so it is not blocking. Without a timeout, functions like recv() , or recvfrom() can block forever.

If you want to force a 2 second interval ( or block ) between calls to recvfrom() and sendto() , put a sleep(2); ( or if on Windows, Sleep(2000); ) statement somewhere in your loop, probably at the bottom.

while(1){
    ...
    }
    sleep(2);  //or on Windows, Sleep(2000);
}

BTW, it is also a good idea to habitually check the return value of any function that has one, in particular if the failure of that function will reek havoc on the rest of your code. eg:

if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(struct timeval)) < 0) {
    perror("Error");
}
...

A few topic related asides:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM