C-在插座上设置超时是不起作用的



我正在使用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;
  }
}

超时(例如您正在实现的内容。)不是延迟语句。相反,这是一种防止呼叫(例如recv())或recvfrom()无限阻止的方法。如果数据流量比设定的超时时间更高,则情况会更好。该功能接收到它,并且程序流程继续。随之而来的是,超时会等待2秒钟才能发生。如果什么都没有发生,那么它允许该方法停止等待,并且要继续执行程序,即不会阻止它。没有超时,诸如recv()recvfrom()之类的函数可以永远阻止。

如果要在呼叫recvfrom()sendto()之间强制2秒的间隔(或 block ),请放置 sleep(2); (如果在Windows上,睡眠(2000); )语句在您的循环中的某个地方,可能在底部。

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

顺便说一句,最好习惯地检查具有任何功能的返回值,特别是如果该功能的失败会对您的其余代码造成破坏。例如:

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

一些与主题有关的主题:

  • 如本文中所述,还有其他更精确的选项睡眠
  • 使用poll()&amp; select()带有插座。(第二个也有利于Poll()。)
  • 讨论在此中使用select()函数的讨论

相关内容

  • 没有找到相关文章

最新更新