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

      假设 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”文件,内容如下:

#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”可执行程序。

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

 

参考:

https://www.yuque.com/docs/share/adecaa3a-ee36-4c17-b911-42c6b10fb2f9

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是使用 libevent 库创建简单的 TCP 服务器的 C++ 实现代码,并附带注释: ```cpp #include <iostream> #include <event2/event.h> #include <event2/listener.h> void read_cb(struct bufferevent* bev, void* ctx) { char buf[1024]; int n; // 从客户端读取数据 while ((n = bufferevent_read(bev, buf, sizeof(buf) - 1)) > 0) { buf[n] = '\0'; std::cout << "Received message: " << buf << std::endl; // 向客户端发送回复消息 const char* replyMsg = "Server received your message\n"; bufferevent_write(bev, replyMsg, strlen(replyMsg)); } } void error_cb(struct bufferevent* bev, short error, void* ctx) { if (error & BEV_EVENT_EOF) { std::cout << "Connection closed." << std::endl; } else if (error & BEV_EVENT_ERROR) { std::cout << "Got an error on the connection: " << evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()) << std::endl; } // 释放 bufferevent 资源 bufferevent_free(bev); } void accept_conn_cb(struct evconnlistener* listener, evutil_socket_t fd, struct sockaddr* address, int socklen, void* ctx) { struct event_base* base = evconnlistener_get_base(listener); // 创建一个新的 bufferevent 用于处理连接 struct bufferevent* bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); bufferevent_setcb(bev, read_cb, NULL, error_cb, NULL); bufferevent_enable(bev, EV_READ | EV_WRITE); } void accept_error_cb(struct evconnlistener* listener, void* ctx) { struct event_base* base = evconnlistener_get_base(listener); int err = EVUTIL_SOCKET_ERROR(); std::cerr << "Error " << err << ": " << evutil_socket_error_to_string(err) << std::endl; event_base_loopexit(base, NULL); } int main() { struct event_base* base = event_base_new(); struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons(8080); // 创建一个监听器,并绑定到指定地址和端口 struct evconnlistener* listener = evconnlistener_new_bind(base, accept_conn_cb, NULL, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, -1, (struct sockaddr*)&sin, sizeof(sin)); if (!listener) { perror("Failed to create listener"); return 1; } evconnlistener_set_error_cb(listener, accept_error_cb); // 进入事件循环 event_base_dispatch(base); // 释放资源 evconnlistener_free(listener); event_base_free(base); return 0; } ``` 这段代码实现了一个简单的 TCP 服务器,监听本地的 8080 端口。当有客户端连接时,服务器会接收客户端发送的消息,并将其打印出来。然后服务器会回复一个简单的消息给客户端。 希望这个示例对你有帮助!如果还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值