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