libevent库的使用--定时器的使用
来源:互联网 发布:软件限制策略组创建 编辑:程序博客网 时间:2024/04/28 23:04
#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. 创建作为数据使用的静态文件
$ ./basichttpfileLoading file: sample.html (8046 bytes)Server started on port 8081
现在,程序可以接受请求了,重新装载计时器也启动了。如果修改 sample.html 的内容,应该会重新装载此文件并在日志中记录一个消息。例如,清单 7 中的输出显示初始装载和两次重新装载:
清单 7. 输出显示初始装载和两次重新装载
$ ./basichttpfileLoading file: sample.html (8046 bytes)Server started on port 8081Reloading file: sample.html (8047 bytes)Reloading file: sample.html (8048 bytes)
注意,要想获得最大的收益,必须确保环境没有限制打开的文件描述符数量。可以使用 ulimit 命令修改限制(需要适当的权限或根访问)。具体的设置取决与您的 OS,但是在 Linux® 上可以用 -n 选项设置打开的文件描述符(和网络套接字)的数量:
1 0
- libevent库的使用--定时器的使用
- 关于libevent定时器使用注意的问题
- 使用libevent编写定时器
- Libevent定时器使用
- libevent的使用
- libevent的使用(socket)
- libevent的使用
- libevent的使用(socket)
- libevent的使用
- 测试libevent的使用
- http libevent的使用
- libevent的使用
- Libevent的使用
- 关于libevent的定时器
- libevent-简单的定时器
- Windows平台下libevent库的使用
- libevent库的使用--内置http服务器
- libevent的使用(socket)
- 1060. Are They Equal (25)
- Histogram Equalization OpenCV offical guild
- 【串口通信】--事件监听
- 图像金字塔
- rails observer
- libevent库的使用--定时器的使用
- 醉汉看守
- 大偏移量下Redis与MongoDB的分页/排名性能比较
- Tomcat安装问题
- ROM BIOS的启动问题(转)
- Android访问网络,使用HttpURLConnection还是HttpClient?
- SQL
- hbase的0.94.4版本一个问题
- java.util.Timer分析源码了解原理