服务端
severe.c
// severe.c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <event2/event.h>#include <event2/listener.h>#include <event2/bufferevent.h>#include "callbacks.h"int main(){ // 创建event base struct event_base* base = NULL; base = event_base_new(); if(base == NULL){ perror("event base new error"); exit(1); } // 填写套接字地址 struct sockaddr_in saddr; memset(&saddr,0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_port = htons(9999); saddr.sin_addr.s_addr = htonl(INADDR_ANY); // 创建listern_cb回调函数的参数 struct CallBackArgs* args = malloc(sizeof(struct CallBackArgs)); args->base = base; // 申请套接字、绑定、监听 struct evconnlistener* evl = NULL; evl = evconnlistener_new_bind(base, listen_cb, (void *)args, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, -1, (struct sockaddr*)&saddr, sizeof(saddr)); if (evl == NULL){ perror("event listener new bind error"); exit(1); } // 开始运行 int code; code = event_base_dispatch(base); if(code == -1){ perror("event base dispatch error"); exit(1); } // 资源关闭 evconnlistener_free(evl); free(args); event_base_free(base); return 0;}
callbacks.h
// callbacks.h#ifndef CLIBEVENT_CALLBACKS_H#define CLIBEVENT_CALLBACKS_H#include <event2/event.h>#include <event2/listener.h>#include <event2/bufferevent.h>/* 自定义回调参数数据结构 */struct CallBackArgs{ struct event_base* base;};/** 监听listen回调函数 * type: evconnlistener_cb * */void listen_cb(struct evconnlistener * evl, evutil_socket_t fd, struct sockaddr * caddr, int socklen, void * args);/** read回调函数 type: bufferevent_data_cb*/void read_cb(struct bufferevent *bfev, void *args);/** * write回调函数 * type: bufferevent_data_cb * */void write_cb(struct bufferevent *bfev, void *args);/** * event回调函数 * type: bufferevent_event_cb * */void event_cb(struct bufferevent *bfev, short what, void *args);#endif //CLIBEVENT_CALLBACKS_H
callbacks.c
// callbacks.c#include "callbacks.h"#include <string.h>#include <ctype.h>#include <stdlib.h>void listen_cb(struct evconnlistener * evl, evutil_socket_t fd, struct sockaddr * caddr, int socklen, void * args){ // 获取参数 struct CallBackArgs* cb_args = (struct CallBackArgs*) args; // 创建buffer event struct bufferevent* bfev = NULL; bfev = bufferevent_socket_new(cb_args->base,fd,BEV_OPT_CLOSE_ON_FREE); if(bfev == NULL){ perror("buffer socket new error"); return; } // 启用读写事件 int code; code = bufferevent_enable(bfev,EV_READ | EV_WRITE); if(code == -1){ perror("buffer event enable error"); bufferevent_free(bfev); return; } // 注册回调函数 bufferevent_setcb(bfev, read_cb, write_cb, event_cb, NULL);}void read_cb(struct bufferevent *bfev, void *args){ //接收数据 char buff[1024] = {0}; int len = bufferevent_read(bfev,buff, sizeof(buff)); printf("接收到了数据:%s",buff); // 处理数据 int i; for(i = 0;i<len ;++i){ buff[i] = toupper(buff[i]); } // 发送数据 int code; code = bufferevent_write(bfev,buff, strlen(buff)+1); if(code == -1){ perror("buffer write error"); return; } printf("我发回了数据:%s",buff);}void write_cb(struct bufferevent *bfev, void *args){ printf("我的数据发送完毕\n");}void event_cb(struct bufferevent *bfev, short what, void *args){ // 出现错误,释放资源,不做额外处理 if(args) free(args); bufferevent_free(bfev); printf("关闭 buffer event\n");}
客户端
// 发送一次数据并受到服务器返回后就退出event循环,结束程序#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <event2/event.h>#include <event2/bufferevent.h>#include <arpa/inet.h>void read_cb(struct bufferevent *bfev, void *args){ char buff[1024] = {0}; int len = bufferevent_read(bfev, buff, sizeof(buff)); printf("从服务器接收到了数据:%s", buff); bufferevent_free(bfev);}void write_cb(struct bufferevent *bfev, void *args){ printf("数据已发送");}void event_cb(struct bufferevent *bfev, short what, void *args){ if (what & BEV_EVENT_CONNECTED) { printf("连接建立完成\n"); return; } if (what & BEV_EVENT_ERROR) { printf("出现错误事件\n"); perror(""); if (args != NULL) free(args); bufferevent_free(bfev); exit(1); } if (what & BEV_EVENT_EOF) { printf("连接已断开\n"); if (args != NULL) free(args); bufferevent_free(bfev); exit(0); }}void std_cb(evutil_socket_t fd, short what, void *sock_bev){ char buff[1024] = {0}; int len = read(fd, buff, sizeof(buff)); struct bufferevent *bev = (struct bufferevent *)sock_bev; int code; code = bufferevent_write(bev, buff, strlen(buff) + 1); if (code == -1) { perror("write to buffer event error"); exit(1); }}int main(){ struct event_base *base = NULL; base = event_base_new(); if (base == NULL) { perror("base new error"); exit(1); } // 要连接的服务器信息 struct sockaddr_in serv; memset(&serv, 0, sizeof(serv)); serv.sin_family = AF_INET; serv.sin_port = htons(9999); inet_pton(AF_INET, "127.0.0.1", &serv.sin_addr.s_addr); // 创建套接字 int fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) { perror("create socket erroe"); exit(1); } printf("套接字创建完成\n"); // 创建本次通信的bufferevent struct bufferevent *bev = NULL; bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); int code; code = bufferevent_socket_connect(bev, (struct sockaddr *)&serv, sizeof(serv)); if (code == -1) { perror("connect error"); exit(1); } bufferevent_setcb(bev, read_cb, write_cb, event_cb, NULL); code = bufferevent_enable(bev, EV_READ | EV_WRITE); if (code == -1) { perror("enable error"); exit(1); } // 创建std输入事件 struct event *ev = NULL; ev = event_new(base, STDIN_FILENO, EV_READ, std_cb, (void *)bev); if (ev == NULL) { perror("创建std event error"); exit(1); } code = event_add(ev, NULL); if (code == -1) { perror("event add error"); exit(1); } // 开始运行 code = event_base_dispatch(base); if (code == -1) { perror("dispatch error"); exit(1); } //printf("event base start\n"); event_base_free(base); printf("event base free\n"); return 0;}