源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

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

  • 时间:2022-09-04 00:09 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:libevent库的使用--定时器的使用实例
[u]复制代码[/u] 代码如下:
#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 filen");           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 %sn",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 %dn", 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. 创建作为数据使用的静态文件
[u]复制代码[/u] 代码如下:
$ ./basichttpfile Loading file: sample.html (8046 bytes) Server started on port 8081
现在,程序可以接受请求了,重新装载计时器也启动了。如果修改 sample.html 的内容,应该会重新装载此文件并在日志中记录一个消息。例如,清单 7 中的输出显示初始装载和两次重新装载: 清单 7. 输出显示初始装载和两次重新装载
[u]复制代码[/u] 代码如下:
$ ./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 选项设置打开的文件描述符(和网络套接字)的数量
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部