#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "tepoll.h"
#define MAX_CLIENT 10000 // 10K !!
#define MAX_PENDING 200
#define MAX_EVENTS 500
#define MAX_ADDR 24
int Listen(const unsigned nport)
{
struct sockaddr_in server_addr, client_addr;
int one=1, addrlen = sizeof(struct sockaddr_in);
int fd_listen;
if ((fd_listen = socket(PF_INET, SOCK_STREAM, 0)) < 0) return -1;
bzero((char *)&server_addr, sizeof(server_addr));
server_addr.sin_family = PF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(nport);
setsockopt(fd_listen, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));
if((bind(fd_listen, (struct sockaddr *)&server_addr, sizeof(server_addr))) < 0 ){
close(fd_listen);
return -2;
}
if(listen(fd_listen, MAX_PENDING) < 0){
close(fd_listen);
return -3;
}
return fd_listen;
}
int SetNonBlocking(int fd)
{
int value;
value = fcntl(fd, F_GETFL, 0);
value |= O_NONBLOCK;
fcntl(fd, F_SETFL, value);
return value;
}
int OnError(const int fd, const int errcode)
{
return errcode;
}
int OnEvent(TEpollEvent &event)
{
int nread, nwrite;
char buf[1024];
if( event.events & EPOLLIN ){
// ³ªÁß¿¡ OnRead(); ·Î ¹Ù²Ü°ÍÀÌ´Ù.
nread = read(event.data.fd, buf, 1024);
if( nread < 1) return OnError(event.data.fd, nread);
else {
nwrite = write(event.data.fd, buf, nread);
buf[0] = 0;
}
}
if( event.events & EPOLLOUT){
// ³ªÁß¿¡ OnWrite(); ·Î ¹Ù²Ü°ÍÀÌ´Ù.
}
if( event.events & EPOLLERR) return OnError(event.data.fd, -1);
return 1;
}
int main(void)
{
int i, n, result;
int fd_listen, fd_client;
TEpoll epoll(MAX_CLIENT);
TEpollEvent events[MAX_EVENTS];
char cliaddr[MAX_ADDR];
struct sockaddr_in client_addr;
int addrlen;
if(! epoll.is_epoll_init){
perror("epoll init error\n");
exit(-1);
}
if((fd_listen = Listen(8000)) < 1){
perror("listen error\n");
exit(-1);
}
epoll.Add(fd_listen);
for(;;){
n = epoll.Do(events, MAX_EVENTS, 0);
for(i=0; i<n; ++i){
if(events[i].data.fd == fd_listen){
fd_client = accept(fd_listen, (struct sockaddr *) &client_addr, (socklen_t *) &addrlen);
if(fd_client < 0){
perror("accept error\n");
continue;
}
strcpy(cliaddr,inet_ntoa(client_addr.sin_addr));
SetNonBlocking(fd_client);
epoll.Add(fd_client);
} else {
if((result = OnEvent(events[i])) < 1){
printf("\nAn error is occured : %d", result);
close(events[i].data.fd);
epoll.Delete(events[i].data.fd);
}
}
}
}
return 0;
}