为了成为自由自在的人而奋斗!
分类: C/C++
2014-12-23 12:57:17
epoll的原理网上很多, 这边实现一个TCP server,备忘, 后续可以快速编程 呵呵
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*
struct epoll_event
{
uint32_t events;
epoll_data_t data;
} __attribute__ ((__packed__));
//union
typedef union epoll_data
{
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
*/
typedef struct epoll_event epoll_event_t;
using namespace std;
#define LISTEN_PORT (6666) //监听端口
#define MAXEVENT_NUM (1024) //最大监听数
//设置为非阻塞socket
int set_nonblock(int fd)
{
int flags = fcntl(fd, F_GETFL, 0);
if (flags == -1)
return -1;
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
int OnRecv(epoll_event_t *pEv)
{
if (pEv->events & EPOLLIN)
{
// Recv
int Recvlen = 0;
char buf[256];
for (;;)
{
Recvlen = recv(pEv->data.fd, buf, 256, 0);
if (Recvlen > 0)
{
cout << "recv len "<< Recvlen << endl;
}
else
{
if ((Recvlen < 0) && (errno == EWOULDBLOCK || errno == EAGAIN))
{
return 0; // Next time to read
}
// TODO: 从epoll队列删除
return -1;
}
}
}
return 0;
}
//新连接, 设置为非阻塞,加入监听
void OnAccept(int newFd, int EpollFd)
{
epoll_event_t ev;
ev.events= EPOLLIN | EPOLLOUT | EPOLLET;
ev.data.fd = newFd;
set_nonblock(newFd);
if( epoll_ctl(EpollFd, EPOLL_CTL_ADD, newFd, &ev)==-1)
{
return ;
}
cout << "accept "<
//处理线程函数
void *ThreadRun(void *argv)
{
epoll_event_t *m_events = (epoll_event_t*)malloc(sizeof(epoll_event_t) * MAXEVENT_NUM);
//创建epoll描述字
int epollFd = epoll_create(MAXEVENT_NUM);
//监听端口socket
int InputFd = *((int*)argv);
if( set_nonblock(InputFd) )
{
return NULL;
}
cout << "Run InputFd"<
epoll_event_t ev;
ev.events= EPOLLIN | EPOLLOUT | EPOLLET;
ev.data.fd = InputFd;
//加入epoll队列
if( epoll_ctl(epollFd, EPOLL_CTL_ADD, InputFd, &ev)==-1)
{
cout << "liste error xxx" <
}
if (listen(InputFd, 5))
{
return NULL;
}
while (1)
{
int ret = epoll_wait(epollFd, m_events,MAXEVENT_NUM, 5000);
if (ret > 0)
{
for (int i = 0; i < ret; ++i)
{
if (m_events[i].data.fd == InputFd)//accept
{
cout << "liste error 1" <
while (1)
{
cout << "liste error 2" <
int so = accept(ev.data.fd, (sockaddr*) &addr, &addrlen);
if (-1 != so)
{
OnAccept(so, epollFd);
}
else
{
break;
}
}
}
else
{
if (OnRecv(&m_events[i]) == -1)
{
epoll_event_t ev;
ev.data.fd=m_events[i].data.fd;
ev.events=0;
if( epoll_ctl(epollFd, EPOLL_CTL_DEL, m_events[i].data.fd, &ev)==-1)
{
cout << ("epoll_ctl(EPOLL_CTL_DEL) failed") <
else
{
cout<<"leave "<
close(m_events[i].data.fd);
}
}
}
}
}
return NULL;
}
int main()
{
int fd = -1;
int flag;
int len = sizeof(int);
fd = socket(AF_INET, SOCK_STREAM, 0);
if (-1 == fd)
{
return -1;
}
struct sockaddr_in m_addr;
m_addr.sin_addr.s_addr = INADDR_ANY ;
m_addr.sin_family = AF_INET;
m_addr.sin_port = htons(LISTEN_PORT);
if (-1 == setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, len))
{
return -1;
}
if (-1 == bind(fd,(sockaddr*)&m_addr,sizeof(m_addr)))
{
return -1;
}
pthread_t thread;
pthread_join(thread, NULL);
return 0;
pthread_create(&(thread), NULL, ThreadRun, (void*)&fd);
cout << "create "<
}