libevent——echo服务器

一会要去开会了,等下午或者晚上抽空再说明一下这个基于libevent写的echo服务器

#include <iostream>
#include <event2/listener.h>
#include <arpa/inet.h>
#include <event2/event.h>
#include <sys/types.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <error.h>
#include <sys/socket.h>

using namespace std;
//拔网线的话进不到这个函数中
void client_cb(int client_sock,short which,void* arg)
{	
	//水平触发,没有处理的话会一直触发事件
	//边沿触发,只会触发一次,没有处理,数据就没了,要加while
	event* ev = static_cast<event*>(arg);
	//判断超时事件
	if(which & EV_TIMEOUT){
		cout<<"time out"<<endl;
		event_free(ev);
		close(client_sock);
		cout<<"客户端超时"<<endl;
		return ;
	}

	char buff[1024] = {0};
	int r = recv(client_sock,buff,sizeof(buff)-1,0);
	if(r == 0){//关闭客户端
		event_free(ev);
		close(client_sock);
		return ;
	}
	buff[r] = '\0';
	cout<<"接收到一条消息"<<buff<<endl;
	send(client_sock,buff,strlen(buff),0);
}
void listen_cb(int server_sock,short,void* arg)
{
    event_base* base = static_cast<event_base*>(arg);	
    cout << "listen_cb" << endl;
    sockaddr_in addr;
    socklen_t size = sizeof(addr);
    int client = accept(server_sock,(sockaddr*)&addr
		    ,&size);
    char ip[16] = { 0 };
    evutil_inet_ntop(AF_INET,&addr.sin_addr,ip,sizeof(ip));
    cout<<"client ip is"<<ip<<endl;

    //客户端读取事件
    event* ev = event_new(base,client,
		    EV_READ | EV_PERSIST,client_cb,
		    event_self_cbarg());
    //event_selef_cbarg()返回当前创建的事件,好直接加载到client_cb
    timeval t={10,0};
    event_add(ev,&t);

}



int main(int argc,char** argv){
	int port = 9996;
	if(argc > 1){
		port = atoi(argv[1]);
	}
	//忽略管道信号
	if(signal(SIGPIPE,SIG_IGN) == SIG_ERR){
		return 1;
	}
	//创建event的上下文
	event_base* base = event_base_new();
	if(base){
                cout<<"event_base_new successful!"<<endl;
        }
	else {
		cout<<"base failed"<<endl;
		return -1;
	}
	evutil_socket_t sock = socket(AF_INET,SOCK_STREAM,0);
	if(sock <=0){
		cerr<<"socket failed"<<strerror(errno)<<endl;
		return -1;
	}
		
	//设置地址复用和非阻塞
	evutil_make_listen_socket_reuseable(sock);
	evutil_make_socket_nonblocking(sock);


	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	inet_pton(AF_INET,"127.0.0.1",&addr.sin_addr);	
	
	if (bind(sock,(sockaddr*)&addr,sizeof(addr)  ) < 0 ) {
		cerr<<"bind error"<<strerror(errno)<<endl;
		return -1;
	}
	listen(sock,10);
	//接受连接事件
//	event *ev = event_new(base,sock,EV_READ | 
//			EV_PERSIST,listen_cb,base);

	//边缘触发

	event *ev = event_new(base,sock,EV_READ | 
			EV_PERSIST | EV_ET,listen_cb,base);


	event_add(ev,NULL);
	

	//事件分发处理,事件主循环
	event_base_dispatch(base);
	


	close(sock);
	if(base)
		event_base_free(base);
	return 0;	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值