-
下载地址:http://libevent.org/ ,下载版本:libevent-2.1.11-stable.tar.gz
-
解压, 目录为...\libevent-2.1.11-stable
-
进入文件夹,找到minheap-internal.h,修改头文件#include "stdint.h"
-
如果编译X64位程序 需修改makefile文件 LIBFLAGS的值后面追加/MACHINE:X64 如果要加调试信息,可以在 CFLAGS中加入/Zi,32位加调试选项是 CFLAGS中加/ZI,当然要调整优化选项/Ox
-
执行命令:nmake /f Makefile.nmake
-
编译成功 命令成功执行后就会生产三个lib文件:libevent.lib libevent_core.lib libevent_extras.lib表示编译成功
-
创建工程
-
拷贝头文件,相关的头文件包括三个地方:(1)libevent-2.0.12-stable\include\* (2)libevent-2.0.12-stable\WIN32-Code\* (3)libevent-2.0.12-stable\*.h
把这些头文件都复制一下放到一个单独的include文件夹中方便管理。
-
拷贝库文件 libevent编译完成后,生成的相关静态库文件包括三个:libevent.lib libevent_core.lib libevent_extras.lib,可以单独建立一个lib文件夹存放;
-
添加链接库 附件依赖项,添加 ws2_32.lib wsock32.lib libevent.lib libevent_core.lib libevent_extras.lib
-
如果编译提示
错误 2 error LNK2019: 无法解析的外部符号 __imp__CryptAcquireContextA@20,该符号在函数 _arc4_seed_win32 中被引用
错误 3 error LNK2019: 无法解析的外部符号 __imp__CryptGenRandom@12,该符号在函数 _arc4_seed_win32 中被引用
需引用AdvAPI32.lib
-
测试demo
#include <stdio.h> #define WIN32_LEAN_AND_MEAN #include <stdlib.h> //#include <unistd.h> //for getopt, fork #include <string.h> //for strcat //for struct evkeyvalq //#include <sys/queue.h> #include <event.h> //for http //#include <evhttp.h> #include <event2/http.h> #include <event2/http_struct.h> #include <event2/http_compat.h> #include <event2/util.h> #include <signal.h> #include "cJSON.h" #define MYHTTPD_SIGNATURE "MoCarHttpd v0.1" //处理模块 void httpd_handler(struct evhttp_request *req, void *arg) { char output[2048] = "\0"; char tmp[1024]; //获取客户端请求的URI(使用evhttp_request_uri或直接req->uri) const char *uri; uri = evhttp_request_uri(req); #if 0 sprintf(tmp, "uri=%s\n", uri);// /data?cmd=new... strcat(output, tmp); #endif sprintf(tmp, "uri=%s\n", req->uri); strcat(output, tmp); //decoded uri char *decoded_uri; decoded_uri = evhttp_decode_uri(uri); sprintf(tmp, "decoded_uri=%s\n", decoded_uri);// /data?cmd= newFile ... strcat(output, tmp); //http://127.0.0.1:8080/username=gailun&passwd=123123 //解析URI的参数(即GET方法的参数) struct evkeyvalq params;//key ---value, key2--- value2// cmd --- newfile fromId == 0 //将URL数据封装成key-value格式,q=value1, s=value2 evhttp_parse_query(decoded_uri, ¶ms); //得到q所对应的value sprintf(tmp, "username=%s\n", evhttp_find_header(¶ms, "username")); strcat(output, tmp); //得到s所对应的value sprintf(tmp, "passwd=%s\n", evhttp_find_header(¶ms, "passwd")); strcat(output, tmp); free(decoded_uri); //获取POST方法的数据 char *post_data = (char *) EVBUFFER_DATA(req->input_buffer); sprintf(tmp, "post_data=%s\n", post_data); strcat(output, tmp); /* 具体的:可以根据GET/POST的参数执行相应操作,然后将结果输出 ... */ //入库 /* 输出到客户端 */ //HTTP header evhttp_add_header(req->output_headers, "Server", MYHTTPD_SIGNATURE); evhttp_add_header(req->output_headers, "Content-Type", "text/plain; charset=UTF-8"); evhttp_add_header(req->output_headers, "Connection", "close"); //输出的内容 struct evbuffer *buf; buf = evbuffer_new(); evbuffer_add_printf(buf, "It works!\n%s\n", output); //将封装好的evbuffer 发送给客户端 evhttp_send_reply(req, HTTP_OK, "OK", buf); evbuffer_free(buf); } //处理模块 void login_handler(struct evhttp_request *req, void *arg) { printf("got connection "); char request_data[4096] = {0}; //获取POST方法的数据 size_t post_size = EVBUFFER_LENGTH(req->input_buffer); char *post_data = (char *) EVBUFFER_DATA(req->input_buffer); memcpy(request_data, post_data, post_size); printf("post_data = [%s], len =%ld\n", post_data, post_size); char username[256] = {0}; char password[256] = {0}; char isDriver[10] = {0}; /* 具体的:可以根据GET/POST的参数执行相应操作,然后将结果输出 ... */ /* ====给服务端的协议==== http://ip:port/login [json_data] { username: "gailun", password: "123123", driver: "yes" } * * * */ cJSON *root = cJSON_Parse(request_data); if (root == NULL) { /* 输出到客户端 */ //HTTP header evhttp_add_header(req->output_headers, "Server", MYHTTPD_SIGNATURE); evhttp_add_header(req->output_headers, "Content-Type", "text/plain; charset=UTF-8"); evhttp_add_header(req->output_headers, "Connection", "close"); //将封装好的evbuffer 发送给客户端 //输出的内容 struct evbuffer *buf; buf = evbuffer_new(); evbuffer_add_printf(buf, "%s", "auth error"); //将封装好的evbuffer 发送给客户端 evhttp_send_reply(req, HTTP_BADREQUEST, "error", buf); evbuffer_free(buf); return; } cJSON* username_obj = cJSON_GetObjectItem(root, "username"); strcpy(username, username_obj->valuestring); cJSON* password_obj = cJSON_GetObjectItem(root, "password"); strcpy(password, password_obj->valuestring); cJSON* isDriver_obj = cJSON_GetObjectItem(root, "driver"); strcpy(isDriver, isDriver_obj->valuestring); printf("username = %s, password = %s, isDriver = %s\n", username, password, isDriver); cJSON_Delete(root); printf("----\n"); //查询数据库 得到查询结果 //给前段回复一个响应结果 cJSON*response_root = cJSON_CreateObject(); cJSON_AddStringToObject(response_root, "result", "ok"); char *response_str = cJSON_Print(response_root); /* 输出到客户端 */ //HTTP header evhttp_add_header(req->output_headers, "Server", MYHTTPD_SIGNATURE); evhttp_add_header(req->output_headers, "Content-Type", "text/plain; charset=UTF-8"); evhttp_add_header(req->output_headers, "Connection", "close"); //输出的内容 struct evbuffer *buf; buf = evbuffer_new(); evbuffer_add_printf(buf, "%s", response_str); //将封装好的evbuffer 发送给客户端 evhttp_send_reply(req, HTTP_OK, "OK", buf); evbuffer_free(buf); cJSON_Delete(response_root); free(response_str); } void show_help() { char *help = "http://localhost:8080\n" "-l <ip_addr> interface to listen on, default is 0.0.0.0\n" "-p <num> port number to listen on, default is 1984\n" "-d run as a deamon\n" "-t <second> timeout for a http request, default is 120 seconds\n" "-h print this help and exit\n" "\n"; fprintf(stderr,"%s",help); } int main(int argc, char *argv[]) { //自定义信号处理函数 WSADATA wsaData; DWORD Ret; if ((Ret = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0) { printf("WSAStartup failed with error %d\n", Ret); return -1; } //默认参数 char *httpd_option_listen = "0.0.0.0"; int httpd_option_port = 7777; int httpd_option_daemon = 0; int httpd_option_timeout = 120; //in seconds 获取参数 //int c; //while ((c = getopt(argc, argv, "l:p:dt:h")) != -1) { // switch (c) { // case 'l' : // httpd_option_listen = optarg; // break; // case 'p' : // httpd_option_port = atoi(optarg); // break; // case 'd' : // httpd_option_daemon = 1; // break; // case 't' : // httpd_option_timeout = atoi(optarg); // break; // case 'h' : // default : // show_help(); // exit(EXIT_SUCCESS); // } //} 判断是否设置了-d,以daemon运行 //if (httpd_option_daemon) { // pid_t pid; // pid = fork(); // if (pid < 0) { // perror("fork failed"); // exit(EXIT_FAILURE); // } // if (pid > 0) { // //生成子进程成功,退出父进程 // exit(EXIT_SUCCESS); // } //} /* 使用libevent创建HTTP Server */ //初始化event API event_init(); //创建一个http server struct evhttp *httpd; httpd = evhttp_start(httpd_option_listen, httpd_option_port); evhttp_set_timeout(httpd, httpd_option_timeout); //也可以为特定的URI指定callback evhttp_set_cb(httpd, "/", httpd_handler, NULL); evhttp_set_cb(httpd, "/login", login_handler, NULL); //循环处理events event_dispatch(); evhttp_free(httpd); return 0; }
Windows下VS2015 编译libevent及使用,编译错误提示
最新推荐文章于 2022-09-09 18:47:38 发布