1

Upon closely scouring through resources, I'm still not entirely sure how to write a proper and usable timer function in C. I am not working with threads (or parallelizable code). I simply want to write a stopwatch function that I can use to trigger a bit of code after a small amount of time has passed.

This is a very common use of a timer, in the situation of "time-out", where I have a client-server set up where the client is sending some data (UDP style with sendto(...) and recvfrom(...)). I have written my system so that the client sends a chunk of data in a packet struct I have defined, and the server processes it via CRC then sends back an acknowledgement packet (ACK) that the msg was received uncorrupted. However, I want to implement a time-out, where if the client does not receive an ACK in a certain period of time, the client resends the data chunk (of course the server is rigged to check for duplicates). I want to nest this bit of timer code in the client, and for some reason do not think this should be so difficult.

I have dug up old signal handling code from work I had done long ago, as this seems to be the only way I commonly see mentioned as a solution, can someone please guide me as to how I can use the following signal handling code to not just receive a timed signal but trigger an action of some sort. Conceptually, I feel it would be: "send data, start timer, after timer expires execute a resend, reset timer...repeat until that ACK received". Better yet, would be an easier way of writing a timer function, but it doesn't look like there's much hope for that given C is a low-level language....

#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;
}
4

1 回答 1

0

Xymotech 提供了我需要的确切功能,在咨询了“select”的 API 之后,其中包括一个小的使用示例,我修改了那里的代码以适应我的需要并编写了一个套接字计时器(对于读取,那些它很容易扩展到写入等,因为“select”具有启用这种检查的参数)。确保您已包含“选择”API 指定的以下库:

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <stdio.h>

以下是我从 API 示例创建的 waittoread(...) 函数,并且运行良好。这在我的特定问题的领域中效果很好,但是,如果有人正在寻找更通用的计时器(即不仅仅是用于定时套接字读取和写入或文件描述符),请咨询信号处理(有点符合我的代码的精神)张贴在我最初的问题中)。

#define S1READY 0x01 // necessary for the function's bitwise OR operation
int waittoread(int s1, int timeout_value){
   fd_set fds; // create set of sockets to be waited on
   struct timeval timeout; // the time-out value
   int rc; // # of sockets that are ready before timer expires
   int result;

   /* Set time limit. */
   timeout.tv_sec = timeout_value;
   timeout.tv_usec = 0;
   /* Create a descriptor set containing the socket.  */
   FD_ZERO(&fds); // MACRO to reset the socket storage set so new ones can be added
   FD_SET(s1, &fds); // add the socket descriptor into the socket set to wait on
   rc = select(sizeof(fds)*4, &fds, NULL, NULL, &timeout); // build the socket-wait system
   // another way of calling select that would be a better approach:
   // rc = select(s1 + 1), &fds, NULL, NULL, &timeout);
   if (rc==-1) {
      perror("Error:  Call to select failed.");
      return -1;
   }
   result = 0;
   if (rc > 0){
      if (FD_ISSET(s1, &fds)) result |= S1READY;  // if the result is non-zero, perform a BIT-wise OR to extract the true socket count #
   }
   return result;
}
于 2013-05-05T19:22:47.083 回答