libevent相关文章.docx
- 文档编号:8828608
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:18
- 大小:30.71KB
libevent相关文章.docx
《libevent相关文章.docx》由会员分享,可在线阅读,更多相关《libevent相关文章.docx(18页珍藏版)》请在冰豆网上搜索。
libevent相关文章
查看文章
bufferevent
2009-11-0917:
08
bufferevent和evbuffer互相配合,就实现了非常好用的带缓冲的IO。
它在非阻塞IO网络编程中非常有用。
举个例子,给定一个非阻塞的网络文件描述符fd,我们想向其中写入很长的一段数据,由于是非阻塞的,我们无法通过一个while循环,将所有的数据写到fd。
这时我们可以使用bufferevent,如下
∙把数据拷贝到一个evbuffer中。
∙让bufferevent监听fd。
∙一旦fd可写,调用n=write(fd,...)往fd中写一定的数据,write()返回真正写的数量。
∙把写了的数据从evbuffer中移去。
bufferevent的实现细节见libevent-bufferevent-detail。
下面给出evbuffer的定义和evbuffer_add()evbuffer_drain()函数。
这些代码加上右边的图例,我们不难理解evbuffer的工作原理,不再赘述细节。
需要注意的地方为
∙void(*cb)(),该指针如果不为NULL,那么每当缓冲区有变化,对应的回调函数就会被调用。
∙evbuffer可以被用作读缓冲,也可以被用作写缓冲,但是一个evbuffer不能既作读缓冲也作写缓冲。
evbuffer图例
structevbuffer{
u_char*buffer;
u_char*orig_buffer;
size_tmisalign;
size_ttotallen;
size_toff;
void(*cb)(structevbuffer*,size_t,size_t,void*);
void*cbarg;
};
int
evbuffer_add(structevbuffer*buf,constvoid*data,size_tdatlen)
{
size_tneed=buf->misalign+buf->off+datlen;
size_toldoff=buf->off;
if(buf->totallen if(evbuffer_expand(buf,datlen)==-1) return(-1); } memcpy(buf->buffer+buf->off,data,datlen); buf->off+=datlen; /*Tellsomeoneaboutchangesinthisbuffer*/ if(datlen&&buf->cb! =NULL) (*buf->cb)(buf,oldoff,buf->off,buf->cbarg); return(0); } voidevbuffer_drain(structevbuffer*buf,size_tlen) { size_toldoff=buf->off; if(len>=buf->off){ buf->off=0; buf->buffer=buf->orig_buffer; buf->misalign=0; gotodone; } buf->buffer+=len; buf->misalign+=len; buf->off-=len; done: /*Tellsomeoneaboutchangesinthisbuffer*/ if(buf->off! =oldoff&&buf->cb! =NULL) (*buf->cb)(buf,oldoff,buf->off,buf->cbarg); } evbuffer还提供其他一些非常好用的接口,列举如下 ∙往buffer中格式化输出 intevbuffer_add_vprintf(structevbuffer*buf,constchar*fmt,va_listap); intevbuffer_add_printf(structevbuffer*buf,constchar*fmt,...) ∙从buffer中读出 intevbuffer_remove(structevbuffer*buf,void*data,size_tdatlen); char*evbuffer_readline(structevbuffer*buffer); 此外,下面的两个函数分别让buffer从一个文件描述符中读取数据和写入数据 intevbuffer_read(structevbuffer*buf,intfd,inthowmuch); intevbuffer_write(structevbuffer*buffer,intfd); Partsoflibeventwhichweuse¶ ThesearethepartsofthelibeventAPIwhichweactuallyuse,andwouldneedreplacingifwedecidedtoditchlibevent: #ifndef_EVENT_H_ #define_EVENT_H_ #ifdef__cplusplus extern"C"{ #endif #defineEV_TIMEOUT0x01 #defineEV_READ0x02 #defineEV_WRITE0x04 #defineEV_SIGNAL0x08 #defineEV_PERSIST0x10/*Persistantevent*/ structevent_base; structevent{ /*...*/ }; void*event_init(void); intevent_base_set(structevent_base*,structevent*); intevent_base_loop(structevent_base*,int); #defineevtimer_add(ev,tv)event_add(ev,tv) #defineevtimer_set(ev,cb,arg)event_set(ev,-1,0,cb,arg) #defineevtimer_del(ev)event_del(ev) #definesignal_add(ev,tv)event_add(ev,tv) #definesignal_set(ev,x,cb,arg)\ event_set(ev,x,EV_SIGNAL|EV_PERSIST,cb,arg) voidevent_set(structevent*,int,short,void(*)(int,short,void*),void*); intevent_add(structevent*,structtimeval*); intevent_del(structevent*); structevbuffer; char*evbuffer_readline(structevbuffer*); intevbuffer_add(structevbuffer*,void*,size_t); intevbuffer_add_printf(structevbuffer*,constchar*fmt,...); structbufferevent{ structevbuffer*input; structevbuffer*output; /*...*/ }; typedefvoid(*evbuffercb)(structbufferevent*,void*); typedefvoid(*everrorcb)(structbufferevent*,shortwhat,void*); structbufferevent*bufferevent_new(intfd, evbuffercbreadcb,evbuffercbwritecb,everrorcberrorcb,void*cbarg); intbufferevent_base_set(structevent_base*base,structbufferevent*bufev); intbufferevent_enable(structbufferevent*bufev,shortevent); intbufferevent_disable(structbufferevent*bufev,shortevent); #ifdef__cplusplus } #endif #endif/*_EVENT_H_*/ libevent 实现telnet代理服务器 (2009-09-1516: 17: 54) 转载 标签: 杂谈 //============================================================================ //Name : libevent_socket.cpp //Author : mengchaoming //Version : //Copyright : beijingtass //Description: HelloWorldinC++,Ansi-style //============================================================================ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include usingnamespacestd; #defineSERVER_PORT 3333 #defineREAL_SERV_PORT23 #defineBUFLEN 1024 typedefstruct { intfd_server; intfd_client; structbufferevent*buf_ev_server; structbufferevent*buf_ev_client; }porxy_server; intGetConnectSocket(char*pServerAddr,intpServerPort) { intm_Socket=0; structsockaddr_indest_addr; //创建发送套接字 m_Socket=socket(AF_INET,SOCK_STREAM,0); if(m_Socket<=0) { //失败 return-1; } //连接客户计算机 bzero(&dest_addr,sizeof(dest_addr)); dest_addr.sin_family=AF_INET; dest_addr.sin_port=htons(REAL_SERV_PORT); if(inet_aton("192.168.5.123",&dest_addr.sin_addr)<0) { printf("192.168.5.123isnotavalidIPaddress\n"); exit (1); } if(connect(m_Socket,(structsockaddr*)&dest_addr,sizeof(dest_addr))==-1) { perror("connecterror! \n"); exit (1); } //连接成功 returnm_Socket; } intsetnonblock(intfd) { intflags; flags=fcntl(fd,F_GETFL); if(flags<0)returnflags; flags|=O_NONBLOCK; if(fcntl(fd,F_SETFL,flags)<0)return-1; return0; } voidon_read_server(structbufferevent*bev,void*arg) { //作为服务器读事件 porxy_server*client=(porxy_server*)arg; if(bev->input->off==0) { printf("Clientdisconnected.\n"); //close(client->fd_server); bufferevent_free(client->buf_ev_client); bufferevent_free(client->buf_ev_server); free(client); return; } elseif(bev->input->off<0) { printf("Socketfailure,disconnectingclient\n"); // close(client->fd_server); bufferevent_free(client->buf_ev_client); bufferevent_free(client->buf_ev_server); free(client); return; } bufferevent_enable(client->buf_ev_server,EV_WRITE); } voidon_write_server(structbufferevent*bev,void*arg) { //作为服务器写事件 porxy_server*client=(porxy_server*)arg; evbuffer_write(bev->input,client->fd_client); //bufferevent_write_buffer(client->buf_ev_client,bev->input); } voidon_read_client(structbufferevent*bev,void*arg) { //作为客户端读事件 porxy_server*client=(porxy_server*)arg; if(bev->input->off==0) { printf("Clientdisconnected.\n"); //close(client->fd_server); bufferevent_free(client->buf_ev_server); bufferevent_free(client->buf_ev_client); free(client); return; } elseif(bev->input->off<0) { printf("Socketfailure,disconnectingclient\n"); // close(client->fd_server); bufferevent_free(client->buf_ev_server); bufferevent_free(client->buf_ev_client); free(client); return; } bufferevent_enable(client->buf_ev_client,EV_WRITE); } voidon_write_client(structbufferevent*bev,void*arg) { //作为客户端写事件 porxy_server*client=(porxy_server*)arg; evbuffer_write(bev->input,client->fd_server); //bufferevent_write_buffer(client->buf_ev_server,bev->input); } voidon_error(structbufferevent*bev,shortwhat,void*arg) { porxy_server*client=(porxy_server*)arg; if(what&EVBUFFER_EOF) { printf("Clientdisconnected.\n"); } else { printf("Clientsocketerror,disconnecting.\n"); } close(client->fd_server); close(client->fd_client); } voidon_accept(intfd,shortev,void*arg) { structsockaddr_inclient_addr; socklen_tclient_len=sizeof(client_addr); porxy_server*client=(porxy_server*)calloc(1,sizeof(porxy_server)); if(client==NULL) { printf("mallocfailed\n"); return; } client->fd_server=accept(fd,(structsockaddr*)&client_addr,&client_len); if(client->fd_server==-1) { warn("failed"); return; } if(setnonblock(client->fd_server)<0) printf("failedtosetclientsocketnon-blocking"); client->buf_ev_server=bufferevent_new(client->fd_server,on_read_server,on_write_server, on_error,client); client->fd_client=GetConnectSocket("192.168.5.123",23); client->buf_ev_client=bufferevent_new(client->fd_client,on_read_client,on_write_client, on_error,client); if(setnonblock(client->fd_client)<0) { printf("failedtosetclientsocketnon-blocking"); } bufferevent_enable(client->buf_ev_client,EV_READ); //bufferevent_enable(client->buf_ev_client,EV_WRITE); bufferevent_enable(client->buf_ev_server,EV_READ); //bufferevent_enable(client->buf_ev_server,EV_WRITE); printf("edconnectionfrom%s\n",inet_ntoa(client_addr.sin_addr)); } intmain(intargc,char**argv) { intlisten_fd; structsockaddr_inlisten_a
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- libevent 相关 文章