libevent庫的使用--定時(shí)器的使用實(shí)例
#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();
}
這個(gè)服務(wù)器的基本原理與前面的示例相同。首先,腳本設(shè)置一個(gè) HTTP 服務(wù)器,它只響應(yīng)對基本 URL 主機(jī)/端口組合的請求(不處理請求 URI)。第一步是裝載文件 (read_file())。在裝載最初的文件時(shí)和在計(jì)時(shí)器觸發(fā)回調(diào)時(shí)都使用此函數(shù)。
read_file() 函數(shù)使用 stat() 函數(shù)調(diào)用檢查文件的修改時(shí)間,只有在上一次裝載之后修改了文件的情況下,它才重新讀取文件的內(nèi)容。此函數(shù)通過調(diào)用 fread() 裝載文件數(shù)據(jù),把數(shù)據(jù)復(fù)制到另一個(gè)結(jié)構(gòu)中,然后使用 strcpy() 把數(shù)據(jù)從裝載的字符串轉(zhuǎn)移到全局字符串中。
load_file() 函數(shù)是觸發(fā)計(jì)時(shí)器時(shí)調(diào)用的函數(shù)。它通過調(diào)用 read_file() 裝載內(nèi)容,然后使用 RELOAD_TIMEOUT 值設(shè)置計(jì)時(shí)器,作為嘗試裝載文件之前的秒數(shù)。libevent 計(jì)時(shí)器使用 timeval 結(jié)構(gòu),允許按秒和毫秒指定計(jì)時(shí)器。計(jì)時(shí)器不是周期性的;當(dāng)觸發(fā)計(jì)時(shí)器事件時(shí)設(shè)置它,然后從事件隊(duì)列中刪除事件。
使用與前面的示例相同的格式編譯代碼:$ gcc -o basichttpfile basichttpfile.c -levent。
現(xiàn)在,創(chuàng)建作為數(shù)據(jù)使用的靜態(tài)文件;默認(rèn)文件是 sample.html,但是可以通過命令行上的第一個(gè)參數(shù)指定任何文件(見 清單 6)。
清單 6. 創(chuàng)建作為數(shù)據(jù)使用的靜態(tài)文件
$ ./basichttpfile
Loading file: sample.html (8046 bytes)
Server started on port 8081
現(xiàn)在,程序可以接受請求了,重新裝載計(jì)時(shí)器也啟動(dòng)了。如果修改 sample.html 的內(nèi)容,應(yīng)該會(huì)重新裝載此文件并在日志中記錄一個(gè)消息。例如,清單 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)
注意,要想獲得最大的收益,必須確保環(huán)境沒有限制打開的文件描述符數(shù)量??梢允褂?ulimit 命令修改限制(需要適當(dāng)?shù)臋?quán)限或根訪問)。具體的設(shè)置取決與您的 OS,但是在 Linux® 上可以用 -n 選項(xiàng)設(shè)置打開的文件描述符(和網(wǎng)絡(luò)套接字)的數(shù)量
上一篇:純C語言:分治快速排序源碼分享
欄 目:C語言
本文標(biāo)題:libevent庫的使用--定時(shí)器的使用實(shí)例
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/3836.html
您可能感興趣的文章
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)式函數(shù)庫
 - 04-02c語言中對數(shù)函數(shù)的表達(dá)式 c語言中對數(shù)怎么表達(dá)
 - 04-02C語言中怎么打出三角函數(shù) c語言中怎么打出三角函數(shù)的值
 - 01-10c語言求1+2+...+n的解決方法
 - 01-10求子數(shù)組最大和的解決方法詳解
 - 01-10深入理解約瑟夫環(huán)的數(shù)學(xué)優(yōu)化方法
 - 01-10深入二叉樹兩個(gè)結(jié)點(diǎn)的最低共同父結(jié)點(diǎn)的詳解
 - 01-10數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)- 解析最少換車次數(shù)的問題詳解
 - 01-10c語言 跳臺(tái)階問題的解決方法
 - 01-10如何判斷一個(gè)數(shù)是否為2的冪次方?若是,并判斷出來是多少次方
 


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
 - 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
 - 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)
 - 04-02c語言用函數(shù)寫分段 用c語言表示分段
 - 04-02c語言中對數(shù)函數(shù)的表達(dá)式 c語言中對
 - 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
 - 04-02c語言沒有round函數(shù) round c語言
 - 04-02c語言分段函數(shù)怎么求 用c語言求分段
 - 04-02C語言中怎么打出三角函數(shù) c語言中怎
 - 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
 
隨機(jī)閱讀
- 08-05織夢dedecms什么時(shí)候用欄目交叉功能?
 - 01-10使用C語言求解撲克牌的順子及n個(gè)骰子
 - 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
 - 01-11ajax實(shí)現(xiàn)頁面的局部加載
 - 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
 - 08-05DEDE織夢data目錄下的sessions文件夾有什
 - 04-02jquery與jsp,用jquery
 - 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
 - 01-10C#中split用法實(shí)例總結(jié)
 - 01-10delphi制作wav文件的方法
 


