1

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;
  }
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Blodorn
  • 73
  • 1
  • 9
  • 2
    A timeout is not a delay statement. rather it waits _up to_ the timeout value for something to happen. If nothing happens, then it allows the method to stop waiting, and for your program execution to continue, i.e. so it is not blocking. – ryyker Feb 28 '19 at 13:19
  • what should I do then to block it for 2 seconds? – Blodorn Feb 28 '19 at 13:26
  • As you described, it should wait for 2 seconds and then continue the program. I don't understand what you said – Blodorn Feb 28 '19 at 13:27
  • 1
    That's not at all what I said. A timeout ***is not*** a delay statement. A _timeout_ is almost universally a term that describes a method to prevent waiting beyond a certain time duration for something to happen. A delay on the other hand is a method that forces a process to wait for a specified time _before_ letting something happen. – ryyker Feb 28 '19 at 13:46
  • To have code wait for one or more seconds you can use `sleep()`. – alk Feb 28 '19 at 13:56
  • 2
    Learn about [poll(2)](http://man7.org/linux/man-pages/man2/poll.2.html). You probably should use it. – Basile Starynkevitch Feb 28 '19 at 14:23
  • 1
    So the question, @Blodorn, is whether you used the wrong term when you said "timeout", or whether you have the wrong idea about what behavior you're trying to implement. Which is it? – John Bollinger Feb 28 '19 at 14:30

1 Answers1

6

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, i.e. 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:

ryyker
  • 22,849
  • 3
  • 43
  • 87