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

标签 c sockets udp timeout

我正在使用 setsockopt() 函数为 recvfrom() 函数设置超时。由于我使用的协议(protocol),我必须首先有 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 上, Sleep(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");
}
...

一些与主题相关的旁白:

关于c - 在套接字上设置超时不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54926437/

相关文章:

macos - Akka,发送 Udp 失败, "Can' t 分配请求的地址”

在c中为linux创建一个新线程?

c++ - 在 Linux 中控制鼠标

c - 对于数组循环使用 int 还是 uint8_t?

Node.js UDP 客户端处理来自 udp 服务器的响应

Python IRC 机器人 : Set variables from channel reading

C++、Linux、套接字发送性能

c - 如何拆分字符串并统计某个单词的使用次数?

c - wsdl2h 无法理解声明部分中提供的省略号 (...)

java.io.StreamCorruptedException : invalid stream header: 4C756E69