zoukankan      html  css  js  c++  java
  • 编译libevent源代码(Windows)

      学习笔记,只是记录本次成功用libevent源代码进行编译。环境为MinGW+VS2008+Msys。

    0.下载libevent库

      http://libevent.org/ 下载stable稳定版的库。

    1.编译

      一开始我用MinGW进行编译的,但是总是出现问题。后来参考了这个博客:http://m.blog.csdn.net/blog/bojie5744/39698599 ,把vs的运行环境包含进来,然后再进行编译

    call "C:Program FilesMicrosoft Visual Studio 9.0VCvcvarsall.bat"

      ./configure ; make ; make install;

      如果不install也可以,libevent头文件在include里面,而生成的库在.libs里面,由于使用的是vs的运行环境。所以libevent源代码编译后的库后缀为lib,而非以前的a文件。复制 libevent.lib;libevent_core.lib;libevent_extra.lib;(最后给出我编译后的文件,方便没有vs编译环境的人下载使用。) 如果为了以后方便,可以把include目录里文件复制到开发环境的include里面,而.libs里面的三个文件也可以拷贝到mingw的lib文件夹里面。

    2.libevent测试代码

    1 #include <winsock2.h>
    2 #include <event2/event.h>
    3 #include <event2/event_struct.h> 
    4 
    5 int main(int argc, char **argv)
    6 {
    7     event timeout;
    8     return (0);
    9 }

      编译选项为

      g++ test.cpp -Iinclude -L. -levent -lws2_32

      注意测试的编译还是不通过的。要把libevent.lib 文件名改为event.lib就可以通过了,具体为什么就还不清楚。至于为什么MS系的lib库和mingw的的a库文件有什么区别,在Windows下mingw高级版本,两者是没有区别的,都是可以调用使用的。

    3.libevent自带的http服务器源码(在sample中的http-server.c)

      1 /*
      2   A trivial static http webserver using Libevent's evhttp.
      3 
      4   This is not the best code in the world, and it does some fairly stupid stuff
      5   that you would never want to do in a production webserver. Caveat hackor!
      6 
      7  */
      8 
      9 /* Compatibility for possible missing IPv6 declarations */
     10 #include "../util-internal.h"
     11 
     12 #include <stdio.h>
     13 #include <stdlib.h>
     14 #include <string.h>
     15 
     16 #include <sys/types.h>
     17 #include <sys/stat.h>
     18 
     19 #ifdef _WIN32
     20 #include <winsock2.h>
     21 #include <ws2tcpip.h>
     22 #include <windows.h>
     23 #include <io.h>
     24 #include <fcntl.h>
     25 #ifndef S_ISDIR
     26 #define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
     27 #endif
     28 #else
     29 #include <sys/stat.h>
     30 #include <sys/socket.h>
     31 #include <signal.h>
     32 #include <fcntl.h>
     33 #include <unistd.h>
     34 #include <dirent.h>
     35 #endif
     36 
     37 #include <event2/event.h>
     38 #include <event2/http.h>
     39 #include <event2/buffer.h>
     40 #include <event2/util.h>
     41 #include <event2/keyvalq_struct.h>
     42 
     43 #ifdef EVENT__HAVE_NETINET_IN_H
     44 #include <netinet/in.h>
     45 # ifdef _XOPEN_SOURCE_EXTENDED
     46 #  include <arpa/inet.h>
     47 # endif
     48 #endif
     49 
     50 #ifdef _WIN32
     51 #ifndef stat
     52 #define stat _stat
     53 #endif
     54 #ifndef fstat
     55 #define fstat _fstat
     56 #endif
     57 #ifndef open
     58 #define open _open
     59 #endif
     60 #ifndef close
     61 #define close _close
     62 #endif
     63 #ifndef O_RDONLY
     64 #define O_RDONLY _O_RDONLY
     65 #endif
     66 #endif
     67 
     68 char uri_root[512];
     69 
     70 static const struct table_entry {
     71     const char *extension;
     72     const char *content_type;
     73 } content_type_table[] = {
     74     { "txt", "text/plain" },
     75     { "c", "text/plain" },
     76     { "h", "text/plain" },
     77     { "html", "text/html" },
     78     { "htm", "text/htm" },
     79     { "css", "text/css" },
     80     { "gif", "image/gif" },
     81     { "jpg", "image/jpeg" },
     82     { "jpeg", "image/jpeg" },
     83     { "png", "image/png" },
     84     { "pdf", "application/pdf" },
     85     { "ps", "application/postsript" },
     86     { NULL, NULL },
     87 };
     88 
     89 /* Try to guess a good content-type for 'path' */
     90 static const char *
     91 guess_content_type(const char *path)
     92 {
     93     const char *last_period, *extension;
     94     const struct table_entry *ent;
     95     last_period = strrchr(path, '.');
     96     if (!last_period || strchr(last_period, '/'))
     97         goto not_found; /* no exension */
     98     extension = last_period + 1;
     99     for (ent = &content_type_table[0]; ent->extension; ++ent) {
    100         if (!evutil_ascii_strcasecmp(ent->extension, extension))
    101             return ent->content_type;
    102     }
    103 
    104 not_found:
    105     return "application/misc";
    106 }
    107 
    108 /* Callback used for the /dump URI, and for every non-GET request:
    109  * dumps all information to stdout and gives back a trivial 200 ok */
    110 static void
    111 dump_request_cb(struct evhttp_request *req, void *arg)
    112 {
    113     const char *cmdtype;
    114     struct evkeyvalq *headers;
    115     struct evkeyval *header;
    116     struct evbuffer *buf;
    117 
    118     switch (evhttp_request_get_command(req)) {
    119     case EVHTTP_REQ_GET: cmdtype = "GET"; break;
    120     case EVHTTP_REQ_POST: cmdtype = "POST"; break;
    121     case EVHTTP_REQ_HEAD: cmdtype = "HEAD"; break;
    122     case EVHTTP_REQ_PUT: cmdtype = "PUT"; break;
    123     case EVHTTP_REQ_DELETE: cmdtype = "DELETE"; break;
    124     case EVHTTP_REQ_OPTIONS: cmdtype = "OPTIONS"; break;
    125     case EVHTTP_REQ_TRACE: cmdtype = "TRACE"; break;
    126     case EVHTTP_REQ_CONNECT: cmdtype = "CONNECT"; break;
    127     case EVHTTP_REQ_PATCH: cmdtype = "PATCH"; break;
    128     default: cmdtype = "unknown"; break;
    129     }
    130 
    131     printf("Received a %s request for %s
    Headers:
    ",
    132         cmdtype, evhttp_request_get_uri(req));
    133 
    134     headers = evhttp_request_get_input_headers(req);
    135     for (header = headers->tqh_first; header;
    136         header = header->next.tqe_next) {
    137         printf("  %s: %s
    ", header->key, header->value);
    138     }
    139 
    140     buf = evhttp_request_get_input_buffer(req);
    141     puts("Input data: <<<");
    142     while (evbuffer_get_length(buf)) {
    143         int n;
    144         char cbuf[128];
    145         n = evbuffer_remove(buf, cbuf, sizeof(cbuf));
    146         if (n > 0)
    147             (void) fwrite(cbuf, 1, n, stdout);
    148     }
    149     puts(">>>");
    150 
    151     evhttp_send_reply(req, 200, "OK", NULL);
    152 }
    153 
    154 /* This callback gets invoked when we get any http request that doesn't match
    155  * any other callback.  Like any evhttp server callback, it has a simple job:
    156  * it must eventually call evhttp_send_error() or evhttp_send_reply().
    157  */
    158 static void
    159 send_document_cb(struct evhttp_request *req, void *arg)
    160 {
    161     struct evbuffer *evb = NULL;
    162     const char *docroot = arg;
    163     const char *uri = evhttp_request_get_uri(req);
    164     struct evhttp_uri *decoded = NULL;
    165     const char *path;
    166     char *decoded_path;
    167     char *whole_path = NULL;
    168     size_t len;
    169     int fd = -1;
    170     struct stat st;
    171 
    172     if (evhttp_request_get_command(req) != EVHTTP_REQ_GET) {
    173         dump_request_cb(req, arg);
    174         return;
    175     }
    176 
    177     printf("Got a GET request for <%s>
    ",  uri);
    178 
    179     /* Decode the URI */
    180     decoded = evhttp_uri_parse(uri);
    181     if (!decoded) {
    182         printf("It's not a good URI. Sending BADREQUEST
    ");
    183         evhttp_send_error(req, HTTP_BADREQUEST, 0);
    184         return;
    185     }
    186 
    187     /* Let's see what path the user asked for. */
    188     path = evhttp_uri_get_path(decoded);
    189     if (!path) path = "/";
    190 
    191     /* We need to decode it, to see what path the user really wanted. */
    192     decoded_path = evhttp_uridecode(path, 0, NULL);
    193     if (decoded_path == NULL)
    194         goto err;
    195     /* Don't allow any ".."s in the path, to avoid exposing stuff outside
    196      * of the docroot.  This test is both overzealous and underzealous:
    197      * it forbids aceptable paths like "/this/one..here", but it doesn't
    198      * do anything to prevent symlink following." */
    199     if (strstr(decoded_path, ".."))
    200         goto err;
    201 
    202     len = strlen(decoded_path)+strlen(docroot)+2;
    203     if (!(whole_path = malloc(len))) {
    204         perror("malloc");
    205         goto err;
    206     }
    207     evutil_snprintf(whole_path, len, "%s/%s", docroot, decoded_path);
    208 
    209     if (stat(whole_path, &st)<0) {
    210         goto err;
    211     }
    212 
    213     /* This holds the content we're sending. */
    214     evb = evbuffer_new();
    215 
    216     if (S_ISDIR(st.st_mode)) {
    217         /* If it's a directory, read the comments and make a little
    218          * index page */
    219 #ifdef _WIN32
    220         HANDLE d;
    221         WIN32_FIND_DATAA ent;
    222         char *pattern;
    223         size_t dirlen;
    224 #else
    225         DIR *d;
    226         struct dirent *ent;
    227 #endif
    228         const char *trailing_slash = "";
    229 
    230         if (!strlen(path) || path[strlen(path)-1] != '/')
    231             trailing_slash = "/";
    232 
    233 #ifdef _WIN32
    234         dirlen = strlen(whole_path);
    235         pattern = malloc(dirlen+3);
    236         memcpy(pattern, whole_path, dirlen);
    237         pattern[dirlen] = '\';
    238         pattern[dirlen+1] = '*';
    239         pattern[dirlen+2] = '';
    240         d = FindFirstFileA(pattern, &ent);
    241         free(pattern);
    242         if (d == INVALID_HANDLE_VALUE)
    243             goto err;
    244 #else
    245         if (!(d = opendir(whole_path)))
    246             goto err;
    247 #endif
    248 
    249         evbuffer_add_printf(evb,
    250                     "<!DOCTYPE html>
    "
    251                     "<html>
     <head>
    "
    252                     "  <meta charset='utf-8'>
    "
    253             "  <title>%s</title>
    "
    254             "  <base href='%s%s'>
    "
    255             " </head>
    "
    256             " <body>
    "
    257             "  <h1>%s</h1>
    "
    258             "  <ul>
    ",
    259             decoded_path, /* XXX html-escape this. */
    260             path, /* XXX html-escape this? */
    261             trailing_slash,
    262             decoded_path /* XXX html-escape this */);
    263 #ifdef _WIN32
    264         do {
    265             const char *name = ent.cFileName;
    266 #else
    267         while ((ent = readdir(d))) {
    268             const char *name = ent->d_name;
    269 #endif
    270             evbuffer_add_printf(evb,
    271                 "    <li><a href="%s">%s</a>
    ",
    272                 name, name);/* XXX escape this */
    273 #ifdef _WIN32
    274         } while (FindNextFileA(d, &ent));
    275 #else
    276         }
    277 #endif
    278         evbuffer_add_printf(evb, "</ul></body></html>
    ");
    279 #ifdef _WIN32
    280         FindClose(d);
    281 #else
    282         closedir(d);
    283 #endif
    284         evhttp_add_header(evhttp_request_get_output_headers(req),
    285             "Content-Type", "text/html");
    286     } else {
    287         /* Otherwise it's a file; add it to the buffer to get
    288          * sent via sendfile */
    289         const char *type = guess_content_type(decoded_path);
    290         if ((fd = open(whole_path, O_RDONLY)) < 0) {
    291             perror("open");
    292             goto err;
    293         }
    294 
    295         if (fstat(fd, &st)<0) {
    296             /* Make sure the length still matches, now that we
    297              * opened the file :/ */
    298             perror("fstat");
    299             goto err;
    300         }
    301         evhttp_add_header(evhttp_request_get_output_headers(req),
    302             "Content-Type", type);
    303         evbuffer_add_file(evb, fd, 0, st.st_size);
    304     }
    305 
    306     evhttp_send_reply(req, 200, "OK", evb);
    307     goto done;
    308 err:
    309     evhttp_send_error(req, 404, "Document was not found");
    310     if (fd>=0)
    311         close(fd);
    312 done:
    313     if (decoded)
    314         evhttp_uri_free(decoded);
    315     if (decoded_path)
    316         free(decoded_path);
    317     if (whole_path)
    318         free(whole_path);
    319     if (evb)
    320         evbuffer_free(evb);
    321 }
    322 
    323 static void
    324 syntax(void)
    325 {
    326     fprintf(stdout, "Syntax: http-server <docroot>
    ");
    327 }
    328 
    329 int
    330 main(int argc, char **argv)
    331 {
    332     struct event_base *base;
    333     struct evhttp *http;
    334     struct evhttp_bound_socket *handle;
    335 
    336     unsigned short port = 0;
    337 #ifdef _WIN32
    338     WSADATA WSAData;
    339     WSAStartup(0x101, &WSAData);
    340 #else
    341     if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
    342         return (1);
    343 #endif
    344     if (argc < 2) {
    345         syntax();
    346         return 1;
    347     }
    348 
    349     base = event_base_new();
    350     if (!base) {
    351         fprintf(stderr, "Couldn't create an event_base: exiting
    ");
    352         return 1;
    353     }
    354 
    355     /* Create a new evhttp object to handle requests. */
    356     http = evhttp_new(base);
    357     if (!http) {
    358         fprintf(stderr, "couldn't create evhttp. Exiting.
    ");
    359         return 1;
    360     }
    361 
    362     /* The /dump URI will dump all requests to stdout and say 200 ok. */
    363     evhttp_set_cb(http, "/dump", dump_request_cb, NULL);
    364 
    365     /* We want to accept arbitrary requests, so we need to set a "generic"
    366      * cb.  We can also add callbacks for specific paths. */
    367     evhttp_set_gencb(http, send_document_cb, argv[1]);
    368 
    369     /* Now we tell the evhttp what port to listen on */
    370     handle = evhttp_bind_socket_with_handle(http, "0.0.0.0", port);
    371     if (!handle) {
    372         fprintf(stderr, "couldn't bind to port %d. Exiting.
    ",
    373             (int)port);
    374         return 1;
    375     }
    376 
    377     {
    378         /* Extract and display the address we're listening on. */
    379         struct sockaddr_storage ss;
    380         evutil_socket_t fd;
    381         ev_socklen_t socklen = sizeof(ss);
    382         char addrbuf[128];
    383         void *inaddr;
    384         const char *addr;
    385         int got_port = -1;
    386         fd = evhttp_bound_socket_get_fd(handle);
    387         memset(&ss, 0, sizeof(ss));
    388         if (getsockname(fd, (struct sockaddr *)&ss, &socklen)) {
    389             perror("getsockname() failed");
    390             return 1;
    391         }
    392         if (ss.ss_family == AF_INET) {
    393             got_port = ntohs(((struct sockaddr_in*)&ss)->sin_port);
    394             inaddr = &((struct sockaddr_in*)&ss)->sin_addr;
    395         } else if (ss.ss_family == AF_INET6) {
    396             got_port = ntohs(((struct sockaddr_in6*)&ss)->sin6_port);
    397             inaddr = &((struct sockaddr_in6*)&ss)->sin6_addr;
    398         } else {
    399             fprintf(stderr, "Weird address family %d
    ",
    400                 ss.ss_family);
    401             return 1;
    402         }
    403         addr = evutil_inet_ntop(ss.ss_family, inaddr, addrbuf,
    404             sizeof(addrbuf));
    405         if (addr) {
    406             printf("Listening on %s:%d
    ", addr, got_port);
    407             evutil_snprintf(uri_root, sizeof(uri_root),
    408                 "http://%s:%d",addr,got_port);
    409         } else {
    410             fprintf(stderr, "evutil_inet_ntop failed
    ");
    411             return 1;
    412         }
    413     }
    414 
    415     event_base_dispatch(base);
    416 
    417     return 0;
    418 }
    View Code

      g++ http-server.c -Iinclude -L. -levent -lws2_32

      这样就可以当作服务器了。

      

      libevent编译后的库下载地址: http://files.cnblogs.com/files/wunaozai/libevent.zip

      本文地址: http://www.cnblogs.com/wunaozai/p/4550084.html 

  • 相关阅读:
    (备忘)解决用Xftp向CentOS7 传文件速度慢的问题
    CentOS上使用ntfs-3g挂载NTFS分区
    tomcat运行一段时间出“org.apache.coyote.http11.Http11Processor.service Error parsing HTTP request header”
    JQuery EasyUI treegrid展开与折叠,以及数据加载两次的问题
    goland 激活码
    golang 之xorm
    golang 之 go module
    golang 之单元测试
    golang 之反射
    golang 之sync &并发安全锁
  • 原文地址:https://www.cnblogs.com/wunaozai/p/4550084.html
Copyright © 2011-2022 走看看