Libevent 常用接口说明
Libevent 常用接口说明:
-
event_base_new
环境配置和初始化 ; -
evutil socket 封装函数,设置 socket 属性,关闭 socket 等:
-
统一 socket 标识;
#ifdef _WIN32 #define evutil_socket_t intptr_t #else #define evutil_socket_t int #endif
-
evutil_make_socket_nonblocking
设置 socket 为非阻塞; -
evutil_make_listen_socket_reuseable
设置 socket 为地址可重用,即将 socket 属性设为SO_REUSEADDR
; -
evutil_closesocket
关闭 socket,Windows 和 Linux 下关闭函数不一样。
-
-
event_new
事件 IO 处理,需要传递有效 socket 或其他文件描述符; -
evconnlistener_new_bind
创建监听,并绑定端口,一般由服务端程序调用; -
bufferevent_*
缓冲 IO 处理,不需要传递有效 socket,只需要传递 buffer 对象即可读写数据; -
event_base_dispatch
事件循环(loop)。
Libevent 应用实例
下面是一个简单的服务器框架的实例,若有连接,则打印出一条 “listen_cb” 信息。
#include <iostream>
#include <string.h>
#ifndef _WIN32
#include <signal.h>
#endif // !_WIN32
#include "event.h"
#include "event2/listener.h"
#define SERVER_PORT 8000
// 接收连接的回调函数
void listen_cb(struct evconnlistener *e,
evutil_socket_t s, struct sockaddr *addr, int socklen, void *arg)
{
std::cout << "listen_cb" << std::endl;
}
int main(int argc, char* argv[])
{
#ifdef _WIN32
// 初始化socket库
WSADATA wsa;
WSAStartup(MAKEWORD(2, 2), &wsa);
#else
// 忽略管道信号,因为发送数据给已关闭的socket会生成SIGPIPE信号,导致进程退出
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
return -1;
#endif
std::cout << "libevent server test" << std::endl;
// 创建libevent上下文
event_base *base = event_base_new();
if (!base) {
std::cout << "event_base_new failed" << std::endl;
return -1;
}
std::cout << "event_base_new success" << std::endl;
// 监听端口,包含 socket/bind/listen
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(SERVER_PORT);
evconnlistener *ev = evconnlistener_new_bind(
base, // libevent上下文
listen_cb, // 接收连接的回调函数
base, // 回调函数获取的参数
LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, // 设置地址重用和关闭同时关闭socket
10, // 连接队列大小,对应listen函数
(struct sockaddr*)&sin, sizeof(sin)); // 绑定socket地址和端口
if (!ev) {
std::cout << "evconnlistener_new_bind failed" << std::endl;
return -1;
}
// 事件分发处理
event_base_dispatch(base);
// 释放资源
evconnlistener_free(ev);
event_base_free(base);
#ifdef _WIN32
WSACleanup();
#endif
return 0;
}
在 VS2015 中编译,若是提示如下错误:
error LNK2001: 无法解析的外部符号 __imp_htons
error LNK2001: 无法解析的外部符号 __imp_WSAStartup
表示没有添加 ws2_32.lib 库,该库是 Windows 自带的 socket 库,凡是进行 socket 编程,都需要加上。另外,在 Windows 上进行网络编程时,还需要调用两个函数
WSAStartup
启动 Windows 套接字;WSACleanup
清理 Windows 套接字。
这两个函数必须在程序开始和结束的地方调用。