Windows 上静态编译 Libevent 2.0.10 并实现一个简单 HTTP 服务器

  [文章作者:张宴 本文版本:v1.0 最后修改:2011.03.30 转载请注明原文链接:http://blog.s135.com/libevent_windows/]

  本文介绍了如何在 Windows 操作系统中,利用微软 Visual Studio 2005 编译生成 Libevent 2.0.10 静态链接库,并利用 Libevent 静态链接库,实现一个简单的 HTTP Web服务器程序:httpd.exe。

  假设 Visual Studio 2005 的安装路径为“D:/Program Files/Microsoft Visual Studio 8/”,Libevent 2.0.10 解压后的路径为“D:/libevent-2.0.10-stable”。


  一、编译生成 Libevent 2.0.10 静态链接库。
  
  1、修改“D:/libevent-2.0.10-stable/event_iocp.c”、“D:/libevent-2.0.10-stable/evthread_win32.c”、“D:/libevent-2.0.10-stable/listener.c”三个文件,在文件开头分别加上一行:

#define _WIN32_WINNT 0x0500



  2、鼠标点击Windows左下角的【开始】-【所有程序】,找到【Microsoft Visual Studio 2005】,执行下图中的脚本:

  点击在新窗口中浏览此图片


  3、按照下图中的方法编译Libevent 2.0.10:

  点击在新窗口中浏览此图片


  4、生成的“libevent.lib”、“libevent_core.lib”、“libevent_extras.lib”三个文件就是我们需要的 Libevent 静态链接库。

  点击在新窗口中浏览此图片


  二、利用 Libevent 静态链接库,实现一个简单的 HTTP Web服务器程序

  1、打开 Visual Studio 2005,新建一个项目

  点击在新窗口中浏览此图片


  2、选择在“d:/test”目录内创建一个“Win32 控制台应用程序”

  点击在新窗口中浏览此图片


  3、按照下图进行选择

  点击在新窗口中浏览此图片


  4、创建完成项目后,会自动生成“d:/test/httpd/”目录,在该目录内创建一个“httpd.c”文件,内容如下:

view plain copy to clipboard print ?
  1. #include <stdio.h>   
  2.   
  3. #define WIN32_LEAN_AND_MEAN   
  4. #include <windows.h>   
  5. #include <winsock2.h>   
  6.   
  7. #include <event.h>   
  8. #include <evhttp.h>   
  9.   
  10. void root_handler(struct evhttp_request *req, void *arg)   
  11. {   
  12.     struct evbuffer *buf = evbuffer_new();   
  13.     if(!buf){   
  14.         puts("failed to create response buffer");   
  15.         return;   
  16.     }   
  17.   
  18.     evbuffer_add_printf(buf, "Hello: %s/n", evhttp_request_uri(req));   
  19.     evhttp_send_reply(req, HTTP_OK, "OK", buf);   
  20. }   
  21.   
  22. void generic_handler(struct evhttp_request *req, void *arg)   
  23. {   
  24.     struct evbuffer *buf = evbuffer_new();   
  25.     if(!buf){   
  26.         puts("failed to create response buffer");   
  27.         return;   
  28.     }   
  29.   
  30.     evbuffer_add_printf(buf, "Requested: %s/n", evhttp_request_uri(req));   
  31.     evhttp_send_reply(req, HTTP_OK, "OK", buf);   
  32. }   
  33.   
  34. int main(int argc, wchar_t* argv[])   
  35. {   
  36.   struct evhttp *httpd;   
  37.   
  38.   WSADATA wsaData;   
  39.   DWORD Ret;   
  40.   if ((Ret = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)  {   
  41.     printf("WSAStartup failed with error %d/n", Ret);   
  42.     return -1;   
  43.   }   
  44.   
  45.     event_init();   
  46.   
  47.     httpd = evhttp_start("0.0.0.0", 8505);   
  48.     if(!httpd){   
  49.     return 1;   
  50.   }   
  51.   
  52.     evhttp_set_cb(httpd, "/", root_handler, NULL);   
  53.     evhttp_set_gencb(httpd, generic_handler, NULL);   
  54.   
  55.   printf("httpd server start OK!/n");   
  56.   
  57.     event_dispatch();   
  58.   
  59.     evhttp_free(httpd);   
  60.   
  61.   WSACleanup();   
  62.     return 0;   
  63. }   

#include <stdio.h> #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h> #include <event.h> #include <evhttp.h> void root_handler(struct evhttp_request *req, void *arg) {     struct evbuffer *buf = evbuffer_new();     if(!buf){         puts("failed to create response buffer");         return;     }     evbuffer_add_printf(buf, "Hello: %s/n", evhttp_request_uri(req));     evhttp_send_reply(req, HTTP_OK, "OK", buf); } void generic_handler(struct evhttp_request *req, void *arg) {     struct evbuffer *buf = evbuffer_new();     if(!buf){         puts("failed to create response buffer");         return;     }     evbuffer_add_printf(buf, "Requested: %s/n", evhttp_request_uri(req));     evhttp_send_reply(req, HTTP_OK, "OK", buf); } int main(int argc, wchar_t* argv[]) {   struct evhttp *httpd;   WSADATA wsaData;   DWORD Ret;   if ((Ret = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)  {     printf("WSAStartup failed with error %d/n", Ret);     return -1;   }     event_init();     httpd = evhttp_start("0.0.0.0", 8505);     if(!httpd){     return 1;   }     evhttp_set_cb(httpd, "/", root_handler, NULL);     evhttp_set_gencb(httpd, generic_handler, NULL);   printf("httpd server start OK!/n");     event_dispatch();     evhttp_free(httpd);   WSACleanup();     return 0; }

  5、回到 Visual Studio 2005,在左侧的【源文件】中选择【添加】-【现有项】,将上一步创建的“httpd.c”文件添加进来。

  点击在新窗口中浏览此图片


  6、在【解决方案“httpd”】上点击鼠标右键,选择【属性】

  点击在新窗口中浏览此图片


  7、将【配置】改为“Release”

  点击在新窗口中浏览此图片


  8、将“D:/libevent-2.0.10-stable/include”整个目录复制到“D:/test/httpd/include”;将“D:/libevent-2.0.10-stable/WIN32-Code”目录内的“tree.h”文件和“event2”子目录,复制到“D:/test/httpd/include/”内;将“D:/libevent-2.0.10-stable/”目录内的所有“*.h”头文件复制到“D:/test/httpd/include/”内。可以在Windows左下角的【开始】-【运行】中输入“cmd”回车,在命令行窗口中执行以下命令,完成复制过程。

mkdir D:/test/httpd/include/
xcopy /E /H /R D:/libevent-2.0.10-stable/include/* D:/test/httpd/include/
xcopy /E /H /R D:/libevent-2.0.10-stable/WIN32-Code/* D:/test/httpd/include/
xcopy /E /H /R D:/libevent-2.0.10-stable/*.h D:/test/httpd/include/



  点击在新窗口中浏览此图片

  点击在新窗口中浏览此图片


  9、回到 Visual Studio 2005,在左侧菜单中【解决方案“httpd”】下面一行【httpd】上点击鼠标邮件,选择【属性】,对每项内容进行修改。下图中红框内的数据即为修改后的数据。

  点击在新窗口中浏览此图片

  点击在新窗口中浏览此图片

  点击在新窗口中浏览此图片

  点击在新窗口中浏览此图片


  注:下图中,附加依赖项填写:

ws2_32.lib wsock32.lib libevent.lib libevent_core.lib libevent_extras.lib


  忽略特定库填写:

libc.lib;msvcrt.lib;libcd.lib;libcmtd.lib;msvcrtd.lib


  点击在新窗口中浏览此图片


  10、完成设置后,在【解决方案“httpd”】上点击鼠标右键,选择【生成解决方案】。如果是重新编译,可以选择【重新生成解决方案】。生成成功后,“d:/test/httpd/Release”目录内的“httpd.exe”即为生成的可执行文件。

  点击在新窗口中浏览此图片


  11、双击“httpd.exe”运行后,打开浏览器,访问“http://127.0.0.1:8505/”,则可以看到以下信息:一个简单的 HTTP Web Server 输出的内容。

  点击在新窗口中浏览此图片


  12、如果你觉得像DOS程序一样的“httpd.exe”可执行文件图标不好看、没有显示版本信息,那么,你可以按照下图步骤,添加ICO图标文件。

  点击在新窗口中浏览此图片

  点击在新窗口中浏览此图片


  13、添加版本信息

  点击在新窗口中浏览此图片

  点击在新窗口中浏览此图片


  14、大功告成,下面显示的是带有自定义图标、版本信息的“httpd.exe”可执行程序。

  点击在新窗口中浏览此图片


  附1:编译好的 Libevent 2.0.10 静态链接库与 httpd 的 Visual Studio 2005 工程源代码下载

下载文件
点击这里下载文件



  附2:ICO图标制作工具下载

下载文件
点击这里下载文件

你可能感兴趣的:(windows,struct,Microsoft,服务器,web服务,图标制作工具)