时间:2021-05-19
复制代码 代码如下:
#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 选项设置打开的文件描述符(和网络套接字)的数量
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了C#多线程学习之使用定时器进行多线程的自动管理。分享给大家供大家参考。具体分析如下:Timer类:设置一个定时器,定时执行用户指定的函数。定时器启
本文研究的主要是C++控制台用定时器的相关实例,具体如下。Timer在MFC程序中的使用在MFC中有一个很好用的定时器函数。使用SetTimer()进行设置定时
javaTimer定时器简单实例代码:publicclassTest{publicstaticvoidmain(String[]args){//Timer定时器
本文实例讲述了VC中定时器的用法,分享给大家供大家参考。具体用法分析如下:定时器在VC中的使用频繁,其原型为:复制代码代码如下:WINUSERAPIUINTWI
环境是:Windows7+Qt4.8.1+QtCreator2.4.1一、定时器Qt中有两种方法来使用定时器,一种是定时器事件,另一种是使用信号和槽。一般使用了