1. Server-side example 1
test_bufferevent1.cpp:
#include <iostream>
#include <event2/event.h>
#include <event2/listener.h>
#include <event2/bufferevent.h>
#include <thread>
#include <errno.h>
#include <string.h>
#ifndef _WIN32
#include <signal.h>
#else
#endif
using namespace std;
#define PORT 5001
void read_cb(bufferevent *be, void *arg){
cout <<"read_cb "<<flush;
//读取输入缓冲数据
char data[1024] = {0};
int len = bufferevent_read(be,data,sizeof(data)-1);
cout<<"["<<data<<"]"<<endl;
if(len <=0 ) return;
if(strstr(data,"quit") != NULL){
cout<<"quit"<<endl;
//退出并关闭socket
bufferevent_free(be);
}
//发送数据 写入到输出缓冲
bufferevent_write(be,"OK",3);
}
void write_cb(bufferevent *be, void *arg){
cout <<"write_cb "<<flush;
}
//错误、超时、链接断开时会进入
void event_cb(bufferevent *be, short events, void *arg){
cout <<"event_cb "<<flush;
}
void listen_cb(evconnlistener *ev, evutil_socket_t s, sockaddr* sin, int slen, void *arg){
cout<<"listen_cb "<<endl;
event_base *base = (event_base *)arg;
//创建bufferevent上下文
//BEV_OPT_CLOSE_ON_FREE 清理bufferevent时关闭socket
bufferevent* bev = bufferevent_socket_new(base,s,BEV_OPT_CLOSE_ON_FREE);
//添加监控事件
bufferevent_enable(bev, EV_READ|EV_WRITE);
//设置回调函数
bufferevent_setcb(bev, read_cb, write_cb, event_cb, base);
}
int main(int argc, char *argv[])
{
#ifdef _WIN32
WSADATA wsa;
int a = WSAStartup(MAKEWORD(2, 2), &wsa);
#else
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
return 1;
#endif
event_base *base = event_base_new();
//创建网络服务器
//设置监听的端口和地址
sockaddr_in sin;
memset(&sin,0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
evconnlistener *ev = evconnlistener_new_bind(base,
listen_cb, //回调函数
base, //回调函数的参数arg
LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE,
10, //listen back
(sockaddr*)&sin,
sizeof(sin)
);
//进入事件主循环
event_base_dispatch(base);
//释放资源
evconnlistener_free(ev);
event_base_free(base);
return 0;
}
Two, server-side example 2
Added "Water Level for Read and Write" parameter.
test_bufferevent2.cpp:
#include <iostream>
#include <event2/event.h>
#include <event2/listener.h>
#include <event2/bufferevent.h>
#include <thread>
#include <errno.h>
#include <string.h>
#ifndef _WIN32
#include <signal.h>
#else
#endif
using namespace std;
#define PORT 5001
void read_cb(bufferevent *be, void *arg){
cout <<"read_cb "<<flush;
//读取输入缓冲数据
char data[1024] = {0};
int len = bufferevent_read(be,data,sizeof(data)-1);
cout<<"["<<data<<"]"<<endl;
if(len <=0 ) return;
if(strstr(data,"quit") != NULL){
cout<<"quit"<<endl;
//退出并关闭socket
bufferevent_free(be);
}
//发送数据 写入到输出缓冲
bufferevent_write(be,"OK",3);
}
void write_cb(bufferevent *be, void *arg){
cout <<"write_cb "<<flush;
}
//错误、超时、链接断开时会进入
void event_cb(bufferevent *be, short events, void *arg){
cout <<"event_cb "<<flush;
//读取超时事件发生后,数据读取停止
if(events & BEV_EVENT_TIMEOUT){
cout<<"BEV_EVENT_TIMEOUT"<<endl;
//可清除无效的连接
bufferevent_free(be);
}else if(events & BEV_EVENT_ERROR){
//可清除无效的连接
bufferevent_free(be);
}else{
cout<<"OTHERS"<<endl;
}
}
void listen_cb(evconnlistener *ev, evutil_socket_t s, sockaddr* sin, int slen, void *arg){
cout<<"listen_cb "<<endl;
event_base *base = (event_base *)arg;
//创建bufferevent上下文
//BEV_OPT_CLOSE_ON_FREE 清理bufferevent时关闭socket
bufferevent* bev = bufferevent_socket_new(base,s,BEV_OPT_CLOSE_ON_FREE);
//添加监控事件
bufferevent_enable(bev, EV_READ|EV_WRITE);
//设置水位
//读取水位
bufferevent_setwatermark(bev, EV_READ,
10,//低水位 -- 数据超过低水位时才会被发送
0 //高水位 0就是无限制,默认值 -- 数据超过高水位时,会被分解成多条发送
);
bufferevent_setwatermark(bev, EV_WRITE,
5,//低水位 0就是无限制,默认值 -- 缓冲数据低于低水位,写入回调被调用
0 //高水位无效
);
//超时时间的设置
timeval t1 = {3, 0}; //3秒
bufferevent_set_timeouts(bev, &t1, 0); //3秒读取超时 超时触发event_cb
//设置回调函数
bufferevent_setcb(bev, read_cb, write_cb, event_cb, base);
}
int main(int argc, char *argv[])
{
#ifdef _WIN32
WSADATA wsa;
int a = WSAStartup(MAKEWORD(2, 2), &wsa);
#else
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
return 1;
#endif
event_base *base = event_base_new();
//创建网络服务器
//设置监听的端口和地址
sockaddr_in sin;
memset(&sin,0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
evconnlistener *ev = evconnlistener_new_bind(base,
listen_cb, //回调函数
base, //回调函数的参数arg
LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE,
10, //listen back
(sockaddr*)&sin,
sizeof(sin)
);
//进入事件主循环
event_base_dispatch(base);
//释放资源
evconnlistener_free(ev);
event_base_free(base);
return 0;
}