libevent库的使用--定时器的使用实例

 更新时间:2013年12月21日 15:29:09   作者:  
这篇文章主要介绍了libevent库的使用--定时器的使用实例,有需要的朋友可以参考一下

复制代码 代码如下:

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <event.h>
#include <evhttp.h>

#define RELOAD_TIMEOUT 5
#define DEFAULT_FILE "sample.html"

char *filedata;
time_t lasttime = 0;
char filename[80];
int counter = 0;

void read_file()
{
  int size = 0;
  char *data;
  struct stat buf;

  stat(filename,&buf);

  if (buf.st_mtime > lasttime)
    {
      if (counter++)
        fprintf(stderr,"Reloading file: %s",filename);
      else
        fprintf(stderr,"Loading file: %s",filename);

      FILE *f = fopen(filename, "rb");
      if (f == NULL)
        {
          fprintf(stderr,"Couldn't open file\n");
          exit(1);
        }

      fseek(f, 0, SEEK_END);
      size = ftell(f);
      fseek(f, 0, SEEK_SET);
      data = (char *)malloc(size+1);
      fread(data, sizeof(char), size, f);
      filedata = (char *)malloc(size+1);
      strcpy(filedata,data);
      fclose(f);


      fprintf(stderr," (%d bytes)\n",size);
      lasttime = buf.st_mtime;
    }
}

void load_file()
{
  struct event *loadfile_event;
  struct timeval tv;

  read_file();

  tv.tv_sec = RELOAD_TIMEOUT;
  tv.tv_usec = 0;

  loadfile_event = malloc(sizeof(struct event));

  evtimer_set(loadfile_event,
              load_file,
              loadfile_event);

  evtimer_add(loadfile_event,
              &tv);
}

void generic_request_handler(struct evhttp_request *req, void *arg)
{
  struct evbuffer *evb = evbuffer_new();

  evbuffer_add_printf(evb, "%s",filedata);
  evhttp_send_reply(req, HTTP_OK, "Client", evb);
  evbuffer_free(evb);
}

int main(int argc, char *argv[])
{
  short          http_port = 8081;
  char          *http_addr = "192.168.0.22";
  struct evhttp *http_server = NULL;

  if (argc > 1)
    {
      strcpy(filename,argv[1]);
      printf("Using %s\n",filename);
    }
  else
    {
      strcpy(filename,DEFAULT_FILE);
    }

  event_init();

  load_file();

  http_server = evhttp_start(http_addr, http_port);
  evhttp_set_gencb(http_server, generic_request_handler, NULL);

  fprintf(stderr, "Server started on port %d\n", http_port);
  event_dispatch();
}

这个服务器的基本原理与前面的示例相同。首先,脚本设置一个 HTTP 服务器,它只响应对基本 URL 主机/端口组合的请求(不处理请求 URI)。第一步是装载文件 (read_file())。在装载最初的文件时和在计时器触发回调时都使用此函数。
read_file() 函数使用 stat() 函数调用检查文件的修改时间,只有在上一次装载之后修改了文件的情况下,它才重新读取文件的内容。此函数通过调用 fread() 装载文件数据,把数据复制到另一个结构中,然后使用 strcpy() 把数据从装载的字符串转移到全局字符串中。
load_file() 函数是触发计时器时调用的函数。它通过调用 read_file() 装载内容,然后使用 RELOAD_TIMEOUT 值设置计时器,作为尝试装载文件之前的秒数。libevent 计时器使用 timeval 结构,允许按秒和毫秒指定计时器。计时器不是周期性的;当触发计时器事件时设置它,然后从事件队列中删除事件。
使用与前面的示例相同的格式编译代码:$ gcc -o basichttpfile basichttpfile.c -levent。
现在,创建作为数据使用的静态文件;默认文件是 sample.html,但是可以通过命令行上的第一个参数指定任何文件(见 清单 6)。
清单 6. 创建作为数据使用的静态文件

复制代码 代码如下:

$ ./basichttpfile
Loading file: sample.html (8046 bytes)
Server started on port 8081

现在,程序可以接受请求了,重新装载计时器也启动了。如果修改 sample.html 的内容,应该会重新装载此文件并在日志中记录一个消息。例如,清单 7 中的输出显示初始装载和两次重新装载:
清单 7. 输出显示初始装载和两次重新装载

复制代码 代码如下:

$ ./basichttpfile
Loading file: sample.html (8046 bytes)
Server started on port 8081
Reloading file: sample.html (8047 bytes)
Reloading file: sample.html (8048 bytes)

注意,要想获得最大的收益,必须确保环境没有限制打开的文件描述符数量。可以使用 ulimit 命令修改限制(需要适当的权限或根访问)。具体的设置取决与您的 OS,但是在 Linux® 上可以用 -n 选项设置打开的文件描述符(和网络套接字)的数量

相关文章

  • CFileDialog的钩子函数解决对话框的多选之DoModal问题

    CFileDialog的钩子函数解决对话框的多选之DoModal问题

    前几天领导问我一个问题:就是使用CFileDialog类在设置多选时选中的文件所放的文件缓冲区不知设置多大合适,本文将详细介绍,需要的朋友可以参考下
    2012-12-12
  • C语言中6组指针和自增运算符结合方式的运算顺序问题

    C语言中6组指针和自增运算符结合方式的运算顺序问题

    本文通过代码实现分析了6种组合:* p++,(* p)++,* (p++),++* p,++( * p), * (++p),需要的朋友可以参考下
    2015-07-07
  • C++实现PyMysql的基本功能实例详解

    C++实现PyMysql的基本功能实例详解

    这篇文章主要介绍了C++实现PyMysql的基本功能,本文通过实例代码给大家介绍的非常详细,对大家的工作或学习有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • C语言实现翻译功能

    C语言实现翻译功能

    这篇文章主要为大家详细介绍了C语言实现简单的翻译功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • C++17使用std::optional表示可能存在的值

    C++17使用std::optional表示可能存在的值

    本文主要介绍了C++17使用std::optional表示可能存在的值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • 深入了解C++中常用的三个智能指针

    深入了解C++中常用的三个智能指针

    C++是一门强大的编程语言,但是在内存管理方面却存在着一些问题。手动管理内存不仅费时费力,而且容易出错。因此,C++中引入了智能指针这一概念,以更好地管理内存,下面就来详细讲讲C++中常用的三个智能指针吧
    2023-05-05
  • C++ Cartographer源码中关于传感器的数据传递实现

    C++ Cartographer源码中关于传感器的数据传递实现

    这篇文章主要介绍了C++ Cartographer源码中关于传感器的数据传递实现,前面已经谈到了Cartographer中添加轨迹的方法和传感器的数据流动走向。发现在此调用了LaunchSubscribers这个函数来订阅相关传感器数据
    2023-03-03
  • C++设计模式之工厂模式

    C++设计模式之工厂模式

    本文是C++设计模式系列文章的第一篇,主要给大家讲述下工厂模式,非常的简单实用,有需要的小伙伴可以参考下
    2016-05-05
  • 详解C++中typedef 和 #define 的区别

    详解C++中typedef 和 #define 的区别

    这篇文章主要介绍了C++中typedef 与 #define 的区别,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • C++超详细讲解数组操作符的重载

    C++超详细讲解数组操作符的重载

    C 语言提供了丰富的操作符,有:算术操作符,移位操作符,位操作符,赋值操作符,单目操作符,关系操作符,逻辑操作符,条件操作符等。接下了让我们探究一下数组操作符的重载
    2022-06-06

最新评论