libevent客户端以及服务器

服务器端:

#include<stdio.h>
#include<string.h>
#include<errno.h>
#include<unistd.h>
#include<event.h>
#include<event2/bufferevent.h>
#include<event2/listener.h>
#include<event2/thread.h>

void socket_read_cb(bufferevent* bev,void* arg)
{
	char msg[4096];

	int len=bufferevent_read(bev,msg,sizeof(msg)-1);
	msg[len]='\0';
	printf("recv the client msg:%s",msg);
	char reply_msg[4096]="I have recvieced the msg:";
	strcat(reply_msg+strlen(reply_msg),msg);
	bufferevent_write(bev,reply_msg,strlen(reply_msg));
}

void socket_event_cb(struct bufferevent* bev,short event,void* arg)
{
	if(event&BEV_EVENT_EOF)
	{
		printf("connection closed\n");
	}
	else if(event&BEV_EVENT_ERROR)
	{
		printf("some other error\n");
	}
	bufferevent_free(bev);
}

/*void accept_cb(int fd,short events,void* arg)
{
	evutil_socket_t sockfd;
	struct sockaddr_in client;
	socklen_t len=sizeof(client);
	sockfd=accept(fd,(struct sockaddr*)&client,&len);
	evutil_make_socket_nonblocking(sockfd);
	printf("accept a client %d\n",sockfd);
	struct event_base* base=(event_base*)arg;
	//struct event* ev=event_new(NULL,-1,0,NULL,NULL);
	//event_assign(ev,base,sockfd,EV_READ|EV_PERSIST,socket_read_cb,(void*)ev);
	//event_add(ev,NULL);
	bufferevent* bev=bufferevent_socket_new(base,sockfd,BEV_OPT_CLOSE_ON_FREE);
	bufferevent_setcb(bev,socket_read_cb,NULL,event_cb,arg);
	bufferevent_enable(bev,EV_READ|EV_PERSIST);
}


int tcp_server_init(int port,int listen_num)
{
	int errno_save;
	evutil_socket_t listener;
	listener=socket(AF_INET,SOCK_STREAM,0);
	if(listener==-1)
	{
		return -1;
	}
	evutil_make_listen_socket_reuseable(listener);
	struct sockaddr_in sin;
	sin.sin_family=AF_INET;
	sin.sin_addr.s_addr=0;
	sin.sin_port=htons(port);
	if(bind(listener,(struct sockaddr*)&sin,sizeof(sin))<0)
	{
		goto error;
	}
	if(listen(listener,listen_num)<0)
	{
		goto error;
	}
	evutil_make_socket_nonblocking(listener);
	return listener;
	error:
		errno_save=errno;
		evutil_closesocket(listener);
		errno=errno_save;
		return -1;
}*/
void listener_cb(evconnlistener* listener,evutil_socket_t fd,struct sockaddr* sock,int socklen,void* arg)
{
	printf("accept a client %d\n",fd);
	event_base* base=(event_base*)arg;
	bufferevent* bev=bufferevent_socket_new(base,fd,BEV_OPT_CLOSE_ON_FREE);
	bufferevent_setcb(bev,socket_read_cb,NULL,socket_event_cb,NULL);
	bufferevent_enable(bev,EV_READ|EV_PERSIST);
}

int main(int argc,char* argv[])
{
	struct sockaddr_in sin;
	memset(&sin,0,sizeof(sin));
	sin.sin_family=AF_INET;
	sin.sin_addr.s_addr=0;
	sin.sin_port=htons(8888);
	struct event_base* base=event_base_new();
	evconnlistener* listener=evconnlistener_new_bind(base,listener_cb,base,LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE,10,(struct sockaddr*)&sin,sizeof(sin));

	event_base_dispatch(base);
	evconnlistener_free(listener);
	event_base_free(base);
	return 0;
}

客户端:

#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<errno.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<event.h>
#include<event2/bufferevent.h>
#include<event2/buffer.h>
#include<event2/util.h>
void cmd_msg_cb(int fd,short events,void* arg)
{
	char msg[1024];
	int ret=read(fd,msg,sizeof(msg));
	if(ret<=0)
	{
		perror("read fail");
		exit(1);
	}
	struct bufferevent* bev=(struct bufferevent*)arg;
	bufferevent_write(bev,msg,ret);
}
void server_msg_cb(struct bufferevent*  bev,void* arg)
{
	char msg[1024];
	int len=bufferevent_read(bev,msg,sizeof(msg));
	msg[len]='\0';
	printf("recv %s from server\n",msg);
}
void event_cb(struct bufferevent* bev,short event,void* arg)
{
	if(event&BEV_EVENT_EOF)
	{
		printf("000connection closed\n");
	}
	else if(event& BEV_EVENT_ERROR)
	{
		printf("some other error\n");
	}
	else if(event&BEV_EVENT_CONNECTED)
	{
		printf("the client has connected to server\n");
		return;
	}
	bufferevent_free(bev);
	struct event* ev=(struct event*)arg;
	event_free(ev);
}
/*int tcp_connect_server(const char* server_ip,int port)
{
	int sockfd,status,save_errno;
	struct sockaddr_in server_addr;
	memset(&server_addr,0,sizeof(server_addr));
	server_addr.sin_family=AF_INET;
	server_addr.sin_port=htons(port);
	status=inet_aton(server_ip,&server_addr.sin_addr);
	if(status==0)
	{
		errno=EINVAL;
		return -1;
	}
	sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(sockfd==-1)
	{
		return -1;
	}
	status=connect(sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr));
	if(status==-1)
	{
		save_errno=errno;
		close(sockfd);
		errno=save_errno;
		return -1;
	}
	evutil_make_socket_nonblocking(sockfd);
	return sockfd;
}*/
int main(int argc,char* argv[])
{
	if(argc<3)
	{
		printf("please input 2 parameters\n");
		return -1;
	}

	struct event_base* base=event_base_new();
	//struct event* ev_sockfd=event_new(base,sockfd,EV_READ|EV_PERSIST,socket_read_cb,NULL);
	//event_add(ev_sockfd,NULL);
	struct bufferevent* bev=bufferevent_socket_new(base,-1,BEV_OPT_CLOSE_ON_FREE);

	struct event* ev_cmd=event_new(base,STDIN_FILENO,EV_READ|EV_PERSIST,cmd_msg_cb,(void*)bev);
	event_add(ev_cmd,NULL);
	struct sockaddr_in server_addr;
	memset(&server_addr,0,sizeof(server_addr));
	server_addr.sin_family=AF_INET;
	server_addr.sin_port=htons(atoi(argv[2]));
	inet_aton(argv[1],&server_addr.sin_addr);
	bufferevent_socket_connect(bev,(struct sockaddr*)&server_addr,sizeof(server_addr));

	bufferevent_setcb(bev,server_msg_cb,NULL,event_cb,(void*)ev_cmd);
	bufferevent_enable(bev,EV_READ|EV_PERSIST);
	event_base_dispatch(base);
	printf("finished\n");
	return 0;
}


当使用libevent库编写一个客户端时,可以使用`bufferevent`结构来简化网络通信的处理。下面是一个简单的libevent客户端的示例代码: ```c #include <event2/event.h> #include <event2/bufferevent.h> void read_cb(struct bufferevent* bev, void* ctx) { char buf[1024]; size_t n; while ((n = bufferevent_read(bev, buf, sizeof(buf))) > 0) { // 处理接收到的数据 // ... } } void write_cb(struct bufferevent* bev, void* ctx) { // 写入数据完成回调 } void event_cb(struct bufferevent* bev, short events, void* ctx) { if (events & BEV_EVENT_CONNECTED) { printf("Connected to server.\n"); // 可以在此处发送数据到服务器 } else if (events & (BEV_EVENT_ERROR | BEV_EVENT_EOF)) { printf("Connection closed or error occurred.\n"); // 可以在此处进行错误处理或重新连接 bufferevent_free(bev); } } int main() { struct event_base* base = event_base_new(); struct bufferevent* bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE); struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = inet_addr("127.0.0.1"); sin.sin_port = htons(12345); bufferevent_setcb(bev, read_cb, write_cb, event_cb, NULL); if (bufferevent_socket_connect(bev, (struct sockaddr*)&sin, sizeof(sin)) < 0) { printf("Failed to connect to server.\n"); return 1; } event_base_dispatch(base); bufferevent_free(bev); event_base_free(base); return 0; } ``` 以上示例代码创建了一个`bufferevent`对象,并设置了读取数据回调函数、写入数据回调函数和事件回调函数。通过调用`bufferevent_socket_connect`函数连接服务器。在事件回调函数中,可以处理连接成功、连接关闭或错误发生的情况。 在主循环中,通过调用`event_base_dispatch`函数进入事件循环,处理网络事件和数据读写。当连接成功后,可以在事件回调函数中发送数据到服务器或在读取数据回调函数中处理接收到的数据。 请注意,以上示例代码仅为演示用途,实际使用时可能需要根据具体需求进行修改和扩展,例如加入超时处理、错误处理等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值