赞
踩
struct bufferevent *bufferevent_socket_new(struct event_base *base,
evutil_socket_t fd,
enum bufferevent_options options);
base: event_base
fd: 封装bufferevent内的 通信文件描述符fd
options:BEV_OPT_CLOSE_ON_FREE (释放资源)
成功:bufferevent 指针; 失败:NULL
void bufferevent_setcb(struct bufferevent *bufev,
bufferevent_data_cb readcb,
bufferevent_data_cb writecb,
bufferevent_event_cb eventcb,
void *cbarg);
bufev: bufferevent_socket_new() 返回值
readcb: 设置 bufferevent 读缓冲,对应回调 read_cb() { bufferevent_read() 读数据 }
writecb: 设置 bufferevent 写缓冲,对应回调 write_cb(){ 给调用者,发送写成功通知} (可传 NULL)
eventcb: 设置 事件回调。 (可传NULL)
cbarg: 上述回调函数使用的 参数
读回调函数原型:
typedef void (*bufferevent_data_cb)(struct bufferevent *bev, void *cbarg);
void read_cb(struct bufferevent *bev, void *cbarg )
{
.....
bufferevent_read(); //read()不能使用,用其替代
}
bufferevent_read() 函数原型:
size_t bufferevent_read(struct bufferevent *bev, void *buf, size_t bufsize);
写回调函数原型:
void write_cb(struct bufferevent *bev, void *cbarg);
bufferevent_write() 函数原型:
int bufferevent_write(struct bufferevent *bufev, const void *data, size_t size);
event 回调函数原型:
typedef void (*bufferevent_event_cb)(struct bufferevent *bev, short events, void *cbarg);
void event_cb(struct bufferevent *bev, short events, void *cbarg)
{
......
}
events: BEV_EVENT_CONNECTED (连接客户端成功事件标志)
默认、write 缓冲区开启、read 缓冲区关闭
启动 :
void bufferevent_enable(struct bufferevent *bufev, short events);
关闭:
void bufferevent_diable(struct bufferevent *bufev, short events);
events: EV_READ、EV_WRITE、EV_READ|EV_WRITE
short bufferevent_get_enabled(struct bufferevent *bufev);
获取缓冲区的状态,需要借助 & 来得到
int bufferevent_socket_connect(struct bufferevent *bev,
struct sockaddr *address, int addrlen);
address、len: connect() 参2/3
struct evconnlistener *evconnlistener_new_bind (
struct event_base *base,
evconnlistener_cb cb,
void *ptr,
unsigned flags,
int backlog,
const struct sockaddr *sa,
int socklen);
base: event_base
cb: 回调函数。 一旦被回调,说明在其内部应该与客户端完成, 数据读写操作,进行通信
ptr: 回调函数的参数
flags: LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE
backlog: listen() 2参。 -1 表最大值
sa:服务器自己的地址结构体
socklen:服务器自己的地址结构体大小
返回值:成功创建的监听器
typedef void (*evconnlistener_cb)(
struct evconnlistener *listener,
evutil_socket_t sock,
struct sockaddr *addr,
int len,
void *ptr);
listener: evconnlistener_new_bind 函数返回值
sock: 用于通信的文件描述符
addr: 客户端的 IP+端口
len: addr的长度
ptr:外部 ptr 传递进来的值
服务器端:
1. 创建event_base event_base_new(); 2. 创建连接监听器 evconnlistener_new_bind(); 进行绑定地址端口设置最大监听数 设置监听回调函数 该函数会创建监听事件添加到event_base中进行监听连接 当有连接成功接入,就会回调监听回调函数 * 设置监听函数 - 创建 bufferevent事件绑定通信描述符,进行通信 bufferevent_socket_new(); - 设置 bufferevent事件设置读、写、其他事件回调函数 bufferevent_setcb(); 读函数bufferevent_read(); 写函数bufferevent_write(); - 使能 读写缓冲区 bufferevent_enable(); 3. 执行 event_base event_base_dispatch(); 4. 资源释放 evconnlistener_free(); event_base_free();
客户端:
服务端:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <event2/event.h> #include <event2/bufferevent.h> #include <event2/listener.h> #define PROT 8888 void write_cb(struct bufferevent *bev, void *cbarg) { printf("send successful...\n"); } void read_cb(struct bufferevent *bev, void *cbarg) { char buf[128] = {0}; bufferevent_read(bev, buf, sizeof(buf)); fputs(buf, stdout); bufferevent_write(bev, "Data received successfully\n", 32); } void event_cb(struct bufferevent *bev, short events, void *cbarg) { //其他事件 处理 } void cb_listener( struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *addr, int len, void *base) { //添加bufferevent事件 绑定通信描述符 进行通信 struct bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); // 给bufferevent缓冲区设置回调函数 bufferevent_setcb(bev, read_cb, write_cb, event_cb, NULL); //读缓冲区使能 bufferevent_enable(bev, EV_READ); } int main(void) { //客户端地址结构 struct sockaddr_in caddr; caddr.sin_family = AF_INET; caddr.sin_port = htons(PROT); caddr.sin_addr.s_addr = htonl(INADDR_ANY); //创建event_base struct event_base *base = event_base_new(); //创建监听服务器 struct evconnlistener *listener = evconnlistener_new_bind(base, cb_listener, base, BEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1, (struct sockaddr*)&caddr, sizeof(caddr)); event_base_dispatch(base); evconnlistener_free(listener); event_base_free(base); return 0; }
客户端:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #include <event2/event.h> #include <event2/bufferevent.h> #include <event2/listener.h> #define PROT 8888 void write_cb(struct bufferevent *bev, void *cbarg) { printf("send successful...\n"); } void read_cb(struct bufferevent *bev, void *cbarg) { char buf[128] = {0}; bufferevent_read(bev, buf, sizeof(buf)); fputs(buf, stdout); } void event_cb(struct bufferevent *bev, short events, void *cbarg) { // } void read_terminal(evutil_socket_t fd, short what, void *cbarg) { char buf[128] = {0}; struct bufferevent *bev = (struct bufferevent*)cbarg; //将标准输入写到服务器 int len = read(STDIN_FILENO, buf, sizeof(buf)); bufferevent_write(bev, buf, len); } int main(void) { //服务器地址结构 struct sockaddr_in caddr; caddr.sin_family = AF_INET; caddr.sin_port = htons(PROT); inet_pton(AF_INET, "127.0.0.1", &caddr.sin_addr); int fd = socket(AF_INET, SOCK_STREAM, 0); struct event_base *base = event_base_new(); //添加 bufferevent 事件 绑定通信文件描述符 进行通信 struct bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); //连接到服务器 bufferevent_socket_connect(bev, (struct sockaddr*)&caddr, sizeof(caddr)); //设置回调函数 bufferevent_setcb(bev, read_cb, write_cb, event_cb, NULL); //使能读缓冲区 bufferevent_enable(bev, EV_READ); //添加 event事件 读标准输入并写到服务器 struct event *ev = event_new(base, STDIN_FILENO, EV_READ|EV_PERSIST, read_terminal, bev); event_add(ev, NULL); event_base_dispatch(base); event_free(ev); event_base_free(base); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。