23,116
社区成员
发帖
与我相关
我的任务
分享
int epoll::setnonblocking(int sock)
{
long arg;
if (fcntl (sock, F_GETFL, &arg) == -1)
{
return 1;
}
arg = arg | O_NONBLOCK;
if (fcntl (sock, F_SETFL, arg) == -1)
{
return 2;
}
return 0;
}
bool epoll::StartServer(const char* ip,int port,int timeout)
{
m_timeout=timeout;
struct epoll_event ev;
ssize_t n;
int ret=0;
int optval=1;
m_epfd = epoll_create(10000);
struct sockaddr_in serveraddr;
m_listenfd = socket(AF_INET,SOCK_STREAM,0);
if(setsockopt(m_listenfd,SOL_SOCKET,SO_REUSEADDR,&optval, sizeof(optval)) == -1)
{
printf("setsockopt error\n");
exit(1);
}
struct linger ln;
ln.l_onoff = 1;
ln.l_linger = 0;
if(setsockopt(m_listenfd, SOL_SOCKET, SO_LINGER, (void *) &ln,sizeof (struct linger)) < 0)
{
printf("setlinger error\n");
exit(1);
}
setnonblocking(m_listenfd);
ev.data.fd = m_listenfd;
ev.events = EPOLLIN | EPOLLHUP | EPOLLERR;
epoll_ctl(m_epfd,EPOLL_CTL_ADD,m_listenfd,&ev);
memset(&serveraddr,0,sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
inet_aton(ip,&(serveraddr.sin_addr));
serveraddr.sin_port = htons(port);
bind(m_listenfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
listen(m_listenfd, 10);
int on = 1;
setsockopt(m_listenfd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
pthread_t tid;
for (int loops = 0; loops < MAX_THREAD_NUM; loops++)
{
ret=pthread_create(&tid,NULL, RecvMsg,this);
if (ret!=0)
{
printf("create thread error\n");
exit(1);
}
}
ret+=pthread_create(&tid,NULL, EpollFunc,this);
}
void* epoll::EpollFun(void* arg)
{
int i,connfd,nfds;
epoll* cs=(epoll*)arg;
struct epoll_event ev,events[10000];
while(true)
{
nfds = epoll_wait(cs->m_epfd,events,10000,-1);
for(i = 0; i < nfds ; ++i)
{
if(events[i].data.fd == cs->m_listenfd)
{
socklen_t clilen= sizeof(struct sockaddr);
struct sockaddr_in clientaddr;
int sign = 1;
while((connfd = accept(cs->m_listenfd,(struct sockaddr *)&clientaddr,&clilen)) < 0)
{
if(errno == EINTR)
continue;
if(errno != EAGAIN && errno != EWOULDBLOCK)
{
sign = 0;
break;
}
}
if(sign == 1)
{
struct linger ln;
ln.l_onoff = 1;
ln.l_linger = 0;
setsockopt(connfd, SOL_SOCKET, SO_LINGER, (void *) &ln,sizeof (struct linger));
struct timeval timeout = {10,0};
setsockopt(connfd,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(struct timeval));
cs->setnonblocking(connfd);
struct epoll_event ev;
char *str = inet_ntoa(clientaddr.sin_addr);
ev.data.u64 = 0UL;
ev.data.fd = connfd;
ev.events = EPOLLIN | EPOLLONESHOT | EPOLLHUP | EPOLLERR ;
epoll_ctl(cs->m_epfd,EPOLL_CTL_ADD,connfd,&ev);
}
}
else if(events[i].events & EPOLLHUP)
{
close(events[i].data.fd);
cs->DelConn(events[i].data.fd);
} else if(events[i].events & EPOLLERR)
{
epoll_ctl(cs->m_epfd,EPOLL_CTL_DEL,events[i].data.fd,&ev);
}
else if(events[i].events & EPOLLIN)
{
pthread_mutex_lock(&cs->m_ClientAcceptMutex);
cs->m_ClientList.push_back(events[i].data.fd);
pthread_cond_signal(&cs->m_cond);
pthread_mutex_unlock(&cs->m_ClientAcceptMutex);
}
else
{
close(events[i].data.fd);
}
}
}
return 0;
}