1、单独起线程进行epoll时间的侦听
void epoll_wrapper::wait_event()
{
struct epoll_event events[EPOLL_SIZE];
while(true)
{
bzero(events,sizeof(events));
int socketnumber = epoll_wait(m_epollfd,events,EPOLL_SIZE,-1);
if(socketnumber < 0)
{
ExitAndPrintErr(__FILE__,__LINE__);
}
for(int i = 0;i < socketnumber;i++)
{
socket_handler * handler = (socket_handler *)events[i].data.ptr;
int socketfd = handler->get_socket();
if(exist_socket(socketfd))
{
pre_handler(handler, &(events[i]));
}
else
{
printf("not found socketfd = %d i = %d/n",socketfd,i);
}
}
}
}
2、接收到事件后的预处理
void epoll_wrapper::pre_handler(socket_handler * handler,struct epoll_event * event)
{
int socketfd = handler->get_socket();
unsigned char type = handler->get_type();
if(type & HANDLER_TYPE_SERVER)
{
if(event->events & EPOLLIN)
{
while(true)
{
int clientSocket = accept(socketfd,NULL,NULL);
if(clientSocket <= 0)
{
if(EAGAIN == errno)
break;
PrintErr(__FILE__,__LINE__);
}
epoll_wrapper::set_nonblocking(clientSocket);
printf("a client is connecting to the server fd = %d/n",clientSocket);
handler->on_accept(clientSocket);
}
}
if(event->events & EPOLLERR)
{
PrintErr(__FILE__,__LINE__);
return ;
}
}
if(type & HANDLER_TYPE_CLIENT)
{
if((event->events & EPOLLERR) && (event->events & EPOLLHUP) && (event->events & EPOLLIN))
{
printf("connect refused/n");
PrintErr(__FILE__,__LINE__);
handler->on_recv_and_send(SOCKET_EVENT_ERR,NULL,0);
return ;
}
if(event->events & EPOLLERR)
{
PrintErr(__FILE__,__LINE__);
handler->on_recv_and_send(SOCKET_EVENT_ERR,NULL,0);
return ;
}
if((event->events & EPOLLHUP))
{
printf("connect successfully/n");
}
if(event->events & EPOLLIN)
{
Buff * t_buf = m_cache.get_freebuf();
if(NULL == t_buf)
{
PrintErr(__FILE__,__LINE__,"mem cache is empty");
return;
}
int max_buf_len = sizeof(Buff);
int recv_count = 0;
bzero(*t_buf,sizeof(Buff));
while(true)
{
int bytecount = recv(socketfd,(char *)(*t_buf + recv_count) ,max_buf_len - recv_count,0);
if(bytecount < 0)
{
if(EAGAIN == errno)
break;
PrintErr(__FILE__,__LINE__);
handler->on_recv_and_send(SOCKET_EVENT_ERR,NULL,0);
m_cache.set_usedbuf(t_buf);
//close(event->data.fd);
return;
}
if(0 == bytecount)
{
PrintErr(__FILE__,__LINE__);
printf("client closed socketfd = %d/n",socketfd);
handler->on_recv_and_send(SOCKET_EVENT_SHUTDOWN,NULL,0);
m_cache.set_usedbuf(t_buf);
//close(event->data.fd);
return;
}
recv_count += bytecount;
}
handler->on_recv_and_send(SOCKET_EVENT_RECV,(char *)*t_buf,recv_count);
m_cache.set_usedbuf(t_buf);
}
if(event->events & EPOLLOUT)
{
Buff * t_buf = handler->get_send_buf();
unsigned int buf_len = handler->get_send_buf_len();
int sendbytecount = send(socketfd,(char *)*t_buf,buf_len,0);
if(sendbytecount < 0)
{
PrintErr(__FILE__,__LINE__);
handler->on_recv_and_send(SOCKET_EVENT_ERR,NULL,0);
//close(event->data.fd);
return;
}
handler->on_recv_and_send(SOCKET_EVENT_SEND,NULL,0);
}
}
}
3、增加一个文件描述符到epfd中
int epoll_wrapper::add_socket(socket_handler * handler)
{
int socketfd = handler->get_socket();
struct epoll_event epollevent;
bzero(&epollevent,sizeof(epollevent));
epollevent.data.ptr = handler;
epollevent.events = EPOLLET | EPOLLIN | EPOLLERR;
handler->set_epoll(this);
AreaLock al(m_lockhandlers);
map<int,socket_handler *>::iterator iter = m_handlers.find(socketfd);
if(iter != m_handlers.end())
{
return -1;
}
pair<int,socket_handler *> mypair(socketfd,handler);
m_handlers.insert(mypair);
if(0 != epoll_ctl(m_epollfd,EPOLL_CTL_ADD,socketfd,&epollevent))
{
ExitAndPrintErr(__FILE__,__LINE__);
}
return 0;
}
(不知道重复增加会怎么样?)
4、修改一个文件描述符的侦听事件
int epoll_wrapper::send_data(socket_handler * handler)
{
int socketfd = handler->get_socket();
if(exist_socket(socketfd))
{
struct epoll_event event;
bzero(&event,sizeof(event));
event.data.ptr = handler;
event.events = EPOLLOUT | EPOLLET | EPOLLIN | EPOLLERR;
if(0 != epoll_ctl(m_epollfd,EPOLL_CTL_MOD,socketfd,&event))
{
ExitAndPrintErr(__FILE__,__LINE__);
}
}
return 0;
}
5、从epfd中删除文件描述符
int epoll_wrapper::remove_socket(int socketfd)
{
AreaLock al(m_lockhandlers);
map_iter iter = m_handlers.find(socketfd);
if(iter != m_handlers.end())
{
m_handlers.erase(iter);
}
if(0 != epoll_ctl(m_epollfd,EPOLL_CTL_DEL,socketfd,NULL))
{
ExitAndPrintErr(__FILE__,__LINE__);
}
return 0;
}
完整下载地址(免费下载,欢迎指正):http://download.csdn.net/source/3315358