libevent总结(四)-------bufferevent实现client

版权声明:本BLOG上原创文章未经本人许可,不得转载,不得用于商业用途及传统媒体,否则属于侵权行为。 https://blog.csdn.net/weixin_40204595/article/details/82530742

写在前面:

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

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

bufferevent实现服务器部分参考: libevent总结(三)-------bufferevent实现server

正文:

一:bufferevent实现客户端流程:

    (1): 创建event_base;
    (2): 创建 bufferevent 事件对象;client监听的fd是自己本地的fd即可。
    (3): bufferevent_socket_connect()连接服务器;
    (4): 使用bufferevent_setcb()函数给bufferevent的read、write、event设置回调函数;
    (5): 使能bufferevent的读写缓冲区;
    (6): bufferevent_read()、bufferevent_write()收发数据;

    (7):启动循环监听:event_base_dispatch();
    (8): 释放资源

二:代码部分,详见注释:


//读数据回调,要在读回调里面调用bufferevent_read()来完成服务器发送过来数据的读取
void read_cb(struct bufferevent *bev, void *ctx)
{
	char buf[1024] = {0x0};
	
	//读取client发过来的数据
	int len = bufferevent_read(bev,buf, 1024);
	printf("client:received %d byts from server,content is %s\n",len,buf);
	
	sleep(3);
	
}

//写回调,当bufferevent_write发送成功后,这里会被调用
void write_cb(struct bufferevent *bev, void *ctx)
{
	printf("client datas send 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");
	}		
}

void timer_cb(evutil_socket_t fd, short event, void *arg)
{
	printf("timer: send data to server\n");
	
	struct bufferevent * bev = (struct bufferevent * )arg;
	
	char *pBuf = "Hello server,this is clint timer to send data for you";
	
	bufferevent_write(bev, pBuf, strlen(pBuf)+1); //注意这个函数执行成功后,我们设置的写回调将会被调用哦
	
	
}


int main(void)
{
	//创建 event_base
	struct event_base *  even_base = event_base_new();
	
	//创建 bufferevent 事件对象,通信的fd放到bufferevent中,客户端只需要监听自己本地的fd即可
	int fd = socket(AF_INET,SOCK_STREAM,0); //用socket创建一个fd
	struct bufferevent * bev = bufferevent_socket_new(even_base, fd,BEV_OPT_CLOSE_ON_FREE);
	
	//打包服务器地址信息
	struct sockaddr_in serv;
	
	memset(serv,0,sizeof(serv));	
	serv.sin_family = AF_INET;
	serv.sin_port = honts(5678);
	inet_pton(AF_INET,"172.168.1.10",&serv.sin_addr.s_addr);
	
	//连接服务器	
	bufferevent_socket_connect(bev,serv, sizeof(serv));
	
	//设置回调:
	//因为client监听的是自己的fd所以client有没有连接成功都可以设置回调来监听读写数据
	bufferevent_setcb(bev,read_cb, write_cb, event_cb, NULL);
	
	//使能读写缓冲区
	bufferevent_enable(bev, EV_READ|EV_WRITE);
	
	//创建一个定时器事件,这里定时给服务器发送数据,并将bufferevent 作为参数给 timer_cb使用
	//因为在timer_cb中会调用 bufferevent_write()发送数据给server
	struct event * event = event_new(even_base, -1, EV_TIMEOUT|EV_PERSIST,timer_cb,bev);
	//添加事件
	struct hal_timeval  tv;
	tv.tv_sec = 10;  //设置时间为10s
	tv.tv_usec = 0; 
	event_add(event, &tv);
	
	//启动循环监听
	event_base_dispatch(even_base);
	
	//释放资源
	event_base_free(even_base);
	
	return 0;
}

扫描二维码关注公众号,回复: 3422586 查看本文章

猜你喜欢

转载自blog.csdn.net/weixin_40204595/article/details/82530742