【发布时间】:2013-05-05 05:55:45
【问题描述】:
在仔细搜索资源后,我仍然不完全确定如何在 C 中编写适当且可用的计时器函数。我没有使用线程(或可并行代码)。我只是想写一个秒表函数,我可以在经过一小段时间后使用它来触发一些代码。
这是计时器的一种非常常见的用法,在“超时”的情况下,我设置了一个客户端-服务器,客户端正在发送一些数据(带有 sendto(...) 的 UDP 样式和recvfrom(...))。我已经编写了我的系统,以便客户端在我定义的数据包结构中发送一大块数据,然后服务器通过 CRC 对其进行处理,然后发回一个确认数据包 (ACK),表明接收到的消息未损坏。但是,我想实现一个超时,如果客户端在一段时间内没有收到 ACK,客户端会重新发送数据块(当然服务器被操纵来检查重复项)。我想在客户端中嵌套这段定时器代码,不知为何觉得这应该不是那么难。
我从很久以前所做的工作中挖掘出旧的信号处理代码,因为这似乎是我通常认为作为解决方案提到的唯一方法,有人可以指导我如何使用以下信号处理代码不仅接收定时信号,而且触发某种动作。从概念上讲,我觉得它是:“发送数据,启动计时器,计时器到期后执行重新发送,重置计时器......重复直到收到 ACK”。更好的是,这将是编写计时器函数的一种更简单的方法,但鉴于 C 是一种低级语言,这似乎没有太大希望......
#include <sys/time.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
extern char *strsignal(int sig);
void timer_handler(int a)
{
// handle signal
printf(">>>> signal caught\n");
printf(">>>> int parameter = %s\n", (char*) strsignal(a));
}
int main(int argc, char* argv[])
{
int retval;
struct itimerval timerValue;
struct itimerval oldTimerValue;
struct sigaction action;
action.sa_handler = &timer_handler;
action.sa_flags = SA_NODEFER;
// initialize timer parameters: expires in 5 seconds
timerValue.it_interval.tv_sec = 5;
timerValue.it_interval.tv_usec = 0;
timerValue.it_value.tv_sec = 5;
timerValue.it_value.tv_usec = 0;
// install signal handler to catch SIGALRM
//signal(SIGALRM, timer_handler);
sigaction(SIGALRM, &action, NULL);
retval = setitimer(ITIMER_REAL, &timerValue, &oldTimerValue);
if (-1 == retval)
perror("Could not set timer");
while(1);
return 0;
}
【问题讨论】:
-
您应该查看
select函数,它允许您等待在套接字处接收数据,以及指定超时值。这听起来像你想要的吗? -
感谢@Xymotech。非常感谢,我在“我最终做了什么”的回答中感谢了你,因为你是指出使用“选择”的人。
标签: c timer timeout signals handler