demo下载地址
链接:https://pan.baidu.com/s/1j21bCNiXHBSFxk2VUCxK6g
提取码:v9hn
#include <event2/event.h> #include <event2/listener.h> #include <string.h> #ifndef _WIN32 #include <signal.h> #endif #include <iostream> using namespace std; int main() { #ifdef _WIN32 //初始化socket库 WSADATA wsa; WSAStartup(MAKEWORD(2,2),&wsa); #else //忽略管道信号,发送数据给已关闭的socket if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) return 1; #endif std::cout << "test server!\n"; //创建libevent的上下文 event_base * base = event_base_new(); if (base) { cout << "event_base_new success!" << endl; } void Server(event_base*base); Server(base); void Client(event_base* base); Client(base); //事件分发处理 if(base) event_base_dispatch(base); if(base) event_base_free(base); #ifdef _WIN32 WSACleanup(); #endif return 0; }
zlib_client.cpp
#include <event2/event.h> #include <event2/listener.h> #include <event2/bufferevent.h> #include <event2/buffer.h> #include <string.h> #ifndef _WIN32 #include <signal.h> #endif #include <iostream> using namespace std; #define FILEPATH "001.txt" bufferevent_filter_result filter_out(evbuffer *s, evbuffer *d, ev_ssize_t limit, bufferevent_flush_mode mode, void *arg) { cout << "filter_out" << endl; return BEV_OK; } static void client_read_cb(bufferevent *bev, void *arg) { //接收服务端发送的OK回复 char data[1024] = { 0 }; int len = bufferevent_read(bev, data, sizeof(data) - 1); cout << data << endl; cout << "client_read_cb " << len << endl; } static void client_write_cb(bufferevent *bev, void *arg) { cout << "client_write_cb" << endl; } static void client_event_cb(bufferevent*be, short events, void *arg) { cout << "client_event_cb " << events << endl; if (events & BEV_EVENT_CONNECTED) { cout << "BEV_EVENT_CONNECTED" << endl; //发送文件名 bufferevent_write(be, FILEPATH, strlen(FILEPATH)); //创建输出过滤 bufferevent * bev_filter = bufferevent_filter_new(be, 0, filter_out, BEV_OPT_CLOSE_ON_FREE,0,0); //设置读取、写入和事件的回调 bufferevent_setcb(bev_filter, client_read_cb, client_write_cb, client_event_cb, arg); bufferevent_enable(bev_filter, EV_READ | EV_WRITE); } } void Client(event_base* base) { cout << "begin Client" << endl; //连接服务端 sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(5001); evutil_inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr.s_addr); bufferevent *bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE); //只绑定事件回调,用来确认连接成功 bufferevent_enable(bev,EV_READ | EV_WRITE); bufferevent_setcb(bev, 0, 0, client_event_cb, 0); bufferevent_socket_connect(bev, (sockaddr*)&sin, sizeof(sin)); //接收回复确认OK }
zlib_server.cpp
#include <event2/event.h> #include <event2/listener.h> #include <event2/bufferevent.h> #include <event2/buffer.h> #include <string.h> #ifndef _WIN32 #include <signal.h> #endif #include <iostream> using namespace std; #define SPORT 5001 bufferevent_filter_result filter_in(evbuffer *s, evbuffer *d, ev_ssize_t limit,bufferevent_flush_mode mode,void *arg) { //1 接收客户端发送的文件名 char data[1024] = { 0 }; int len = evbuffer_remove(s, data, sizeof(data) - 1); cout << "server recv "<<data << endl; evbuffer_add(d, data, len); return BEV_OK; } static void read_cb(bufferevent *bev, void *arg) { //2 回复OK bufferevent_write(bev, "OK", 2); } static void event_cb(bufferevent *bev,short events, void *arg) { } static void listen_cb(struct evconnlistener * e, evutil_socket_t s, struct sockaddr *a, int socklen, void *arg) { cout << "listen_cb" << endl; event_base *base = (event_base *)arg; //1 创建一个bufferevent 用来通信 bufferevent *bev = bufferevent_socket_new(base, s, BEV_OPT_CLOSE_ON_FREE); //2 添加过滤 并设置输入回调 bufferevent *bev_filter = bufferevent_filter_new(bev, filter_in,//输入过滤函数 0,//输出过滤 BEV_OPT_CLOSE_ON_FREE,//关闭filter同时管理bufferevent 0, //清理回调 0 //传递参数 ); //3 设置回调 读取 事件(处理连接断开) bufferevent_setcb(bev_filter, read_cb, 0, event_cb, 0); bufferevent_enable(bev_filter, EV_READ | EV_WRITE); } void Server(event_base*base) { cout << "begin Server" << endl; //监听端口 //socket ,bind,listen 绑定事件 sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(SPORT); evconnlistener *ev = evconnlistener_new_bind(base, // libevent的上下文 listen_cb, //接收到连接的回调函数 base, //回调函数获取的参数 arg LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE,//地址重用,evconnlistener关闭同时关闭socket 10, //连接队列大小,对应listen函数 (sockaddr*)&sin, //绑定的地址和端口 sizeof(sin) ); }