libevent服务器
介绍
首先包含两个头文件
#include <event2/event.h>
#include <event2/bufferevent.h>
base
base是里边的基本东西,必须要有的,通过以下接口创建和销毁
event_base_new 创建
event_base_free 释放
event
event是base之后需要有的,对于服务器来说就是设置监听用的
event_new 创建
event_free 释放
event_add 添加事件
event_base_dispatch 事件循环
bufferevent
bufferevent这个就是带有缓冲区的事件了,这里主要介绍以下几个
bufferevent_socket_new 创建
bufferevent_free 释放
bufferevent_setcb 设置回调
bufferevent_enable 启用bufferevent
bufferevent_read 读取
bufferevent_write 写入
大概就这些了
Demo
#include <iostream>
#include <unistd.h>
#include <event2/event.h>
#include <event2/bufferevent.h>
void read_cb(struct bufferevent *bev, void *ctx)
{
std::string strBuf;
int cfd = bufferevent_getfd(bev);
std::cout << "cfd: " << cfd << "send: ";
while(1)
{
char buf[1024] = { 0 };
int n = 0;
n = bufferevent_read(bev, buf, sizeof(buf));
if(n == -1)
{
std::cout << "bufferevent_read error" << std::endl;
return;
}
else if(n == 0)
{
break;
}
else
{
std::cout << buf;
strBuf += buf;
}
}
if(bufferevent_write(bev, strBuf.c_str(), strBuf.size()) == -1)
{
//error
std::cout << "bufferevent_write error" << std::endl;
}
}
void write_cb(struct bufferevent *bev, void *ctx)
{
std::cout << "send finish" << std::endl;
}
void error_cb(struct bufferevent *bev, short what, void *ctx)
{
int cfd = bufferevent_getfd(bev);
if(what & BEV_EVENT_ERROR)
{
std::cout << "cfd: " << cfd << "error!" << std::endl;
}
else if(what & BEV_EVENT_EOF)
{
std::cout << "cfd: " << cfd << "connection closed!" << std::endl;
}
else if(what & BEV_EVENT_TIMEOUT)
{
std::cout << "cfd: " << cfd << "timeout!" << std::endl;
}
bufferevent_free(bev);
}
void accept_cb(evutil_socket_t lfd, short event, void* arg)
{
struct event_base* base = (struct event_base*)arg;
struct sockaddr_in client_in;
socklen_t client_size = sizeof(client_in);
int cfd = accept(lfd, (sockaddr*)&client_in, &client_size);
if(cfd == -1)
{
perror("accept err:");
return;
}
struct bufferevent* bev = bufferevent_socket_new(base, cfd, BEV_OPT_CLOSE_ON_FREE);
bufferevent_setcb(bev, read_cb, write_cb, error_cb, NULL);
bufferevent_enable(bev, EV_READ | EV_PERSIST);
}
int main()
{
int lfd = socket(AF_INET, SOCK_STREAM, 0);
if(lfd == -1)
{
perror("socket err:");
return -1;
}
struct sockaddr_in server_in;
server_in.sin_addr.s_addr = htonl(INADDR_ANY);
server_in.sin_family = AF_INET;
server_in.sin_port = htons(33333);
if(bind(lfd, (const sockaddr*)&server_in, sizeof(server_in)) == -1)
{
perror("bind err:");
return -1;
}
if(listen(lfd, 30) == -1)
{
perror("listen err:");
return -1;
}
//evutil_make_socket_nonblocking(lfd);
struct event_base* base = event_base_new();
struct event* lev = event_new(base, lfd, EV_WRITE | EV_READ | EV_PERSIST, accept_cb, (void*)base);
event_add(lev, NULL);
event_base_dispatch(base);
event_base_free(base);
return 0;
}