在套接字上设置超时不起作用

Blo*_*orn 1 c sockets udp timeout

我正在使用该setsockopt()函数在函数上设置超时recvfrom().由于我使用的协议,我必须首先超时2秒,然后4,6,直到最大.但是当我使用该功能时,它似乎有0.01秒的超时,因为它无需等待即可发送8个数据包.

//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;
  }
}
Run Code Online (Sandbox Code Playgroud)

ryy*_*ker 6

超时(例如您正在实现的内容)不是延迟语句.相反,它是为了防止一个呼叫,诸如方法recv(),或recvfrom()无限期地阻止.如果数据流量显示的时间早于设置的超时,那就更好了.该函数接收它,程序流程继续.超时,就像你拥有它一样,等待最多2秒钟才能发生.如果没有任何反应,那么它允许方法停止等待,并使程序执行继续,即它不会阻塞.没有超时,功能就像recv(),或者recvfrom()可以永远阻止.

如果你想在调用和之间强制一个2秒的间隔(或阻止),那就放一个睡眠(2); (或者,如果在Windows上,Sleep(2000);)语句中的某个地方,可能在底部.recvfrom()sendto()

while(1){
    ...
    }
    sleep(2);  //or on Windows, Sleep(2000);
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,习惯性地检查任何具有一个函数的函数的返回值也是一个好主意,特别是如果该函数的失败会对你的其余代码造成严重破坏.例如:

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

一些相关的主题: