libevent相关文章.docx

上传人:b****7 文档编号:8828608 上传时间:2023-02-02 格式:DOCX 页数:18 大小:30.71KB
下载 相关 举报
libevent相关文章.docx_第1页
第1页 / 共18页
libevent相关文章.docx_第2页
第2页 / 共18页
libevent相关文章.docx_第3页
第3页 / 共18页
libevent相关文章.docx_第4页
第4页 / 共18页
libevent相关文章.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

libevent相关文章.docx

《libevent相关文章.docx》由会员分享,可在线阅读,更多相关《libevent相关文章.docx(18页珍藏版)》请在冰豆网上搜索。

libevent相关文章.docx

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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学 > 生物学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1