如何在c中的socket编程中接收数据时实现定时器

时间:2012-10-09 07:07:21

标签: c linux sockets timer

我已经完成了与定时器相关的不同问题。它接缝我的代码应该工作。但是在接收套接字上的数据时发生超时时它不起作用。我有一个名为timeout_timer的函数,函数的定义如下:

timeout_timer(long seconds, long micro_seconds)
{
    struct itimerval *alarm_set;

    if (micro_seconds >= MILLION) {
        seconds = seconds + micro_seconds / MILLION;
        micro_seconds = micro_seconds % MILLION;
    }

    alarm_set = malloc(sizeof (struct itimerval));

    alarm_set->it_value.tv_sec = seconds;
    alarm_set->it_value.tv_usec = micro_seconds;

    alarm_set->it_interval.tv_sec = (seconds == 0 && micro_seconds == 0) ? 0 : 2;
    alarm_set->it_interval.tv_usec = 0;

    if (setitimer(ITIMER_REAL, alarm_set, (struct itimerval *) NULL) == -1) {
        pause();
    }
    free(alarm_set);
}

我已将此timeout_timer函数调用如下:

timeout_timer(3,0);

memset(rcv_msg,0x0, MAX_MSG); 
if ((n = recv(sd, rcv_msg, MAX_MSG, 0)) <= 0) 
{
    timeout_timer(0,0);
    close(sd);
    break;  
}
else
{
    timeout_timer(0,0);
    trim_space(rcv_msg);
}

在超时限制内收到数据时,它可以正常工作。但是当计时器到期时它会卡住。 请帮我搞清楚。

2 个答案:

答案 0 :(得分:1)

使用或实施您的事件循环,可能使用libevent或Gtk / Glib或Qt / QCore,也可以使用poll(2)timerfd_create(2)系统调用来实现。

BTW,在多线程方法中,您可以让主线程执行事件循环,其他线程执行其他处理。

答案 1 :(得分:1)

您的SIGALRM信号处理程序是什么样的?

空体很好,但你需要一个真正的处理程序,安装而不用 SA_RESTART标志;否则信号传递不会中断阻塞I / O功能。

由于信号可能已经到达已经有一些数据可用的点(只是所有预期),因此中断的I / O功能可能会返回一个短计数。这可能很难检测,因此最好重复超时中断(很快,比如每十毫秒)。当您的代码注意到它已被中断时,您应该明确撤防计时器,以停止重复中断。

我个人也会使用全局volatile sig_atomic_t keep_running;标志,在设置超时时设置为非零,并由信号处理程序清除。