简体   繁体   English

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

[英]Setting a timeout on a socket is not working

I'm using the setsockopt() function to set a timeout on the recvfrom() function. 我正在使用setsockopt()函数在recvfrom()函数上设置超时。 Because of the protocol I am using, I have to first have a timeout of 2 secs, then 4, 6, until a max. 由于我使用的协议,我必须首先具有2秒的超时时间,然后是4、6,直到最大时间。 But when I use the function, it seems to have a 0.01 seconds timeout because it sends 8 packets without waiting. 但是当我使用该功能时,它似乎有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;
  }
}

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. 相反,它是一种防止无限期阻止诸如recv()recvfrom()的调用的方法。 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. 超时,您需要等待2秒钟才能发生。 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. 没有超时,诸如recv()recvfrom()类的函数可能会永远阻塞。

If you want to force a 2 second interval ( or block ) between calls to recvfrom() and sendto() , put a sleep(2); 如果要在对recvfrom()sendto()调用之间强制2秒的间隔(或阻塞 sendto() ,请放置sleep(2); ( or if on Windows, Sleep(2000); ) statement somewhere in your loop, probably at the bottom. (或者在Windows中为Sleep(2000); )语句,该语句可能在循环的某个位置,可能在底部。

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: 一些与主题相关的方面:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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