libevent通常作为服务端,但是有场景会作为客户端去抓取别的服务,通常可以使用libcurl去抓取,但是会使整个线程处于等待状态,这时可以使用libevent客户端模式,使请求完全异步。
#ifndef _EVENT_CURL_H_ #define _EVENT_CURL_H_ #include <string> using namespace std; typedef void (*RequestFinishHandler)(struct evhttp_request *req, void *arg); struct event_base; class EventHttpReq { public: EventHttpReq() { m_time_out = 300; finish_handler = NULL; finish_arg = NULL; } string m_url; string m_post_data; int m_time_out; RequestFinishHandler finish_handler; void *finish_arg; }; class EventCurl { public: static bool curl(EventHttpReq &eventHttpReq, struct event_base *, struct evhttp_connection *& conn); }; #endif
#include <signal.h> #include <sys/socket.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <arpa/inet.h> #include <netinet/tcp.h> #include "EventCurl.h" #include "event2/util.h" #include "event2/http.h" #include "event2/http_struct.h" #include "event2/buffer.h" bool EventCurl::curl(EventHttpReq &eventHttpReq, struct event_base *base, struct evhttp_connection *& conn) { struct evhttp_request *req; const char *scheme, *host, *path, *query; struct evhttp_uri *http_uri = evhttp_uri_parse(eventHttpReq.m_url.c_str()); if (NULL == http_uri) { return false; } string uri; int port; scheme = evhttp_uri_get_scheme(http_uri); if (scheme == NULL || (strcasecmp(scheme, "https") != 0 && strcasecmp(scheme, "http") != 0)) { evhttp_uri_free(http_uri); return false; } host = evhttp_uri_get_host(http_uri); if (NULL == host) { evhttp_uri_free(http_uri); return false; } port = evhttp_uri_get_port(http_uri); if (port == -1) { port = (strcasecmp(scheme, "http") == 0) ? 80 : 443; } path = evhttp_uri_get_path(http_uri); if (path == NULL || strlen(path) == 0) { uri = "/"; } else { uri = path; } query = evhttp_uri_get_query(http_uri); if (query != NULL) { uri += "?"; uri += query; } conn = evhttp_connection_base_new(base, NULL, host, port); if (NULL == conn) { evhttp_uri_free(http_uri); return false; } req = evhttp_request_new(eventHttpReq.finish_handler, eventHttpReq.finish_arg); if (NULL == req) { evhttp_connection_free(conn); evhttp_uri_free(http_uri); conn = NULL; return false; } evhttp_add_header(req->output_headers, "Host", host); int make_request_ret = 0; if (eventHttpReq.m_post_data.size() > 0) //post请求,则加入post的内容 { evbuffer_add(req->output_buffer, eventHttpReq.m_post_data.c_str(), eventHttpReq.m_post_data.size()); make_request_ret = evhttp_make_request(conn, req, EVHTTP_REQ_POST, uri.c_str()); } else //get请求 { make_request_ret = evhttp_make_request(conn, req, EVHTTP_REQ_GET, uri.c_str()); } if (make_request_ret != 0) { evhttp_connection_free(conn); evhttp_request_free(req); evhttp_uri_free(http_uri); conn = NULL; return false; } evhttp_connection_set_timeout(req->evcon, eventHttpReq.m_time_out); evhttp_uri_free(http_uri); return true; }
收到返回结果,或异常时的处理。
void finish_handler(struct evhttp_request *req, void *arg) { EParser *parser = (EParser *)arg; parser->m_curl_time = parser->m_timer.ElapseTime(); int http_code = 0; if (req != NULL) { http_code = evhttp_request_get_response_code(req); //http码 parser->m_http_code = http_code; if (http_code == HTTP_OK) { int s = evbuffer_remove(req->input_buffer, &parser->curl_result, E_MAX_SIZE_BUF); struct evkeyvalq* headers = evhttp_request_get_input_headers(req); //http头部 for (evkeyval* header = headers->tqh_first; header != NULL; header = header->next.tqe_next) { parser->m_receive_header.insert(std::pair<string, string>(header->key, header->value)); } } } parser->m_is_finish = true; ProcessRequestSend(EParser); }
相关推荐
这些文件可以作为学习和参考的实例,通过阅读和运行代码,可以更好地理解libevent的使用方法。 总结,libevent是一个强大的工具,它简化了网络编程中的事件处理,使得开发者能更专注于业务逻辑。这个项目提供了一个...
1. 初始化libevent:在程序启动时,你需要调用`event_base_new()`函数来创建一个事件基础结构,这将作为所有事件处理的中心。 2. 注册事件:对于网络I/O事件,如TCP连接,我们可以使用`event_new()`创建一个新的...
最终选择了比较强健并且夸平台的libevent作为主要实现目标(当然其他的也都有实现, 主要实现的还有libuv和netty), 并用于做TCP服务程序工具。希望能给大家帮助。另外看到也有朋友要用MFC来实现的, 正好给他们参考...
这个函数需要基础事件结构体作为参数,返回一个HTTP客户端句柄。 3. **配置HTTP请求**:对于GET请求,可以直接指定URL;而对于POST请求,需要额外设置HTTP头信息,指定请求方法为POST,并提供数据。可以使用`...
总结起来,Linux FastDFS结合libevent-2.1.11-stable可以构建一个高性能的分布式文件系统,libevent作为底层的事件驱动库,为FastDFS提供了强大的网络通信支持,使系统在处理大量并发连接时保持高效和稳定。...
libevent-2.1.12-stable作为libevent库的一个稳定版本,不仅提供了跨平台的事件处理机制,还通过持续优化提升了性能和易用性。理解和掌握libevent的使用,对于提升网络编程的效率和质量具有重要的意义。开发者可以...
1. **libevent核心概念:**libevent提供了一个事件基础架构,可以将事件模型(如 epoll、poll、select)与各种网络协议(如TCP、UDP、Unix域套接字)结合,简化了编写高性能网络服务器和客户端的工作。 2. **事件...
Libevent作为一个强大的事件库,为开发者提供了在Windows环境下构建高性能网络服务的便利。通过理解和熟练使用libevent,可以极大地提高程序的并发处理能力和响应速度。配合提供的静态库和头文件,开发者可以直接在...
Libevent作为一个强大的事件库,为开发者提供了简洁的API,使得编写高性能、高并发的网络服务成为可能。在PHP环境中,正确理解和使用libevent,可以显著提升服务器的处理能力,为互联网应用提供更加流畅的服务体验...
libevent 是一个开源、跨平台的事件通知库,它允许程序员编写高性能、异步的网络服务器和客户端程序。在本文中,我们将深入探讨 libevent 的核心概念、功能特性、使用场景以及如何进行实际编程。 ### 1. libevent ...
2. 监听套接字:使用libevent或event的监听函数创建一个监听套接字,用于接收新的客户端连接。 3. 处理连接:当有新的连接到达时,注册对应的读事件,处理客户端发送的数据。 4. 发送响应:在收到数据后,根据业务...
与传统的基于线程或进程的并发模型相比,`libevent`通过事件循环机制实现了更为高效的任务调度,特别适用于需要处理大量客户端连接的服务器应用。`libevent`支持多种操作系统,包括Linux、BSD变种以及Windows等。 #...
例如,你可以创建一个简单的服务器或客户端来测试Libevent的功能。完成后,点击工具栏上的“生成”按钮编译项目。如果一切顺利,你应该能在“输出”窗口看到编译成功的消息。如果遇到错误,检查配置是否正确,或者...
### libevent中文参考手册...总之,libevent作为一个强大的跨平台异步IO库,旨在简化网络编程的同时保持高性能和灵活性。无论是对于构建高性能Web服务器还是开发复杂的企业级应用,libevent都是一个值得考虑的选择。
在“配置管理器”中,选择“x64”作为目标平台,然后进行编译和调试。 总结,使用libevent进行C++开发涉及了库的配置、事件基础的创建、事件的添加与删除,以及事件回调函数的编写。通过理解和实践这些知识点,你...
这个库特别适用于编写高性能、可扩展的网络服务器或客户端,因为它能够有效地处理大量的并发连接。 **1. 安装和配置VS2008** 首先,确保你已经安装了Microsoft Visual Studio 2008。如果没有,可以从微软官方网站...
libevent 作为一种事件驱动的解决方案,其核心在于提供了对底层网络后端的高效封装。它不是替换原有的系统调用如 `select()` 或 `poll()`,而是在这些基础之上添加了一层高级抽象,使得用户可以更加专注于业务逻辑而...
Android系统作为基于Linux内核的移动操作系统,理论上可以支持Libevent。然而,由于Android的环境与标准Linux有所不同,因此需要对Libevent进行一定的修改和配置才能使其在Android上正常运行。这通常涉及到NDK...
作为TCP server如果耗时操作处理得当实测能够稳定在线10000+客户端。无内存泄露,相比其他开源网络库,cpu、内存占用更低。具体TCP SERVER使用方式参考LibeventServer.cpp,也可以联系本人交流。