libevent总结(三)-------bufferevent实现server

6 篇文章 165 订阅 ¥9.90 ¥99.00

写在前面:

 libevent常规事件的总结使用步骤参考:libevent总结(一)-------libevent常规事件

bufferevent 原理部分和函数分析部分参考:libevent总结(二)-------libevent bufferevent事件

 

正文:

一:bufferevent实现服务器流程:

    (1):创建event_base;
    (2):创建监听服务器:evconnlistener_new_bind();设置其回调函数,当有客户端成功连接时,这个回调函数会被调用;
    (3):封装回调函数例如函数名叫listen_cb();在函数内部完成,完成与客户端通信;

    (4):在listen_cb()回调中,创建创建 bufferevent 事件对象;
    (5):使用bufferevent_setcb()函数给bufferevent的read、write、event设置回调函数;
    (6):使能bufferevent的读写缓冲区;
    (7):当监听的事件满足时,read_cb()会被调用,在其内部bufferev_read()读数据;


    (8):启动循环监听:event_base_dispatch();
    (9):释放连接;

    注意:(4)、(5)、(6)、(7)步都是在监听器的回调函数中做的,因为server的bufferevent_socket_new()中的
fd参数是client的fd,在客户端连接成功后才可以进行数据的读写。

二:代码实现部分,注释部分已很详细



//读数据回调,要在读回调里面调用bufferevent_read()来完成对数据的读取
//然后调用bufferevent_write()函数将信息反馈给client
void read_cb(struct bufferevent *bev, void *ctx)
{
	char buf[1024] = {0x0};
	
	//读取client发过来的数据
	int len = bufferevent_read(bev,buf, 1024);
	printf("received %d byts,content is %s\n",len,buf);
	
	//告诉client已成功接受数据
	char *p = "Hi Client, Server received data succeed";
	
	bufferevent_write(bev, p, strlen(p)+1); //注意这个函数执行成功后,我们设置的写回调将会被调用哦
	
	sleep(3);
	
}
//写回调,当bufferevent_write发送成功后,这里会被调用
void write_cb(struct bufferevent *bev, void *ctx)
{
	printf("datas tx succeed\n");
}

//事件回调
void event_cb(struct bufferevent *bev, short what, void *ctx)
{
	if(what & BEV_EVENT_READING	)
	{
		printf("BEV_EVENT_READING event happend\n");
		//次错误发送要释放 bufferevent资源
		bufferevent_free(bev);
	}	
	if(what & BEV_EVENT_WRITING	)
	{
		printf("BEV_EVENT_WRITING event happend\n");
		//次错误发送要释放 bufferevent资源
		bufferevent_free(bev);	}		
	if(what & BEV_EVENT_EOF	)
	{
		printf("BEV_EVENT_EOF event happend\n");
		//次错误发送要释放 bufferevent资源
		bufferevent_free(bev);	}		
	if(what & BEV_EVENT_ERROR	)
	{
		printf("BEV_EVENT_ERROR event happend\n");
		//次错误发送要释放 bufferevent资源
		bufferevent_free(bev);	}		
	if(what & BEV_EVENT_TIMEOUT	)
	{
		printf("BEV_EVENT_TIMEOUT event happend\n");
		//次错误发送要释放 bufferevent资源
		bufferevent_free(bev);	}		
	if(what & BEV_EVENT_CONNECTED )
	{
		printf("BEV_EVENT_CONNECTED  event happend\n");
	}		
}


//监听回调函数,注意,有回调来说明,客户端已经与服务器连接
//另外,回调中的sock和 addr都是客户端的信息
void listener_cb(struct evconnlistener *listener,evutil_socket_t sock, struct sockaddr *addr, int len, void *ptr)
{
	printf("client connect server succeess\n");	
	
	//基于传进来的 event_base来创建bufferevent对象
	event_base *  base = (event_base * )ptr;
	
	struct bufferevent * bev = bufferevent_socket_new(base, sock,BEV_OPT_CLOSE_ON_FREE);
	
	//给bufferevent事件对象设置回调
	 bufferevent_setcb(bev,read_cb, write_cb, event_cb, NULL);
	 
	 //使能读写缓冲区
	 bufferevent_enable(bev, EV_READ|EV_WRITE);
	
}



int main(void)
{
	
	//创建 event_base
	struct event_base *  even_base = event_base_new();
	
	//设置服务器的地址和IP
	struct sockaddr_in serv;
	
	memset(serv,0,sizeof(serv));
	serv.sin_family = AF_INET;
	serv.sin_port = honts(5678);
	serv.sin_addr.s_addr = hontl(INADDR_ANY);
	
	// 创建监听服务器
	struct evconnlistener *  listener = NULL;
	
	//注意这里第三个参数为even_base的目的是当连接成功后,将这个参数传递给回调,
	//回调中基于这个event_base来创建bufferevent 对象结构体
	listener = evconnlistener_new_bind(even_base,listener_cb, even_base, LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1,
								&serv, sizeof(serv));
	
	
	//启动循环监听
	event_base_dispatch(even_base);
	
	//释放资源
	evconnlistener_free(listener);
	event_base_free(even_base);
	
	return 0;
}







 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KiranWang

一起努力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值